blob: 94650dc3acd26a5cfb4dd9b71c2614b973255cb6 [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>
Christopher N. Hesse297a6362017-01-28 12:40:45 +01005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#define LOG_TAG "audio_hw_primary"
20/*#define LOG_NDEBUG 0*/
21/*#define VERY_VERY_VERBOSE_LOGGING*/
22#ifdef VERY_VERY_VERBOSE_LOGGING
23#define ALOGVV ALOGV
24#else
25#define ALOGVV(a...) do { } while(0)
26#endif
27
28#define _GNU_SOURCE
29#include <errno.h>
30#include <pthread.h>
31#include <stdint.h>
32#include <sys/time.h>
33#include <stdlib.h>
34#include <math.h>
35#include <dlfcn.h>
Christopher N. Hesse297a6362017-01-28 12:40:45 +010036
37#include <cutils/log.h>
38#include <cutils/str_parms.h>
39#include <cutils/atomic.h>
40#include <cutils/sched_policy.h>
41#include <cutils/properties.h>
42
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010043#include <samsung_audio.h>
44
Christopher N. Hesse297a6362017-01-28 12:40:45 +010045#include <hardware/audio_effect.h>
46#include <system/thread_defs.h>
47#include <audio_effects/effect_aec.h>
48#include <audio_effects/effect_ns.h>
49#include "audio_hw.h"
Christopher N. Hesse757ac412017-01-28 14:42:48 +010050#include "compress_offload.h"
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +010051#include "voice.h"
Christopher N. Hesse297a6362017-01-28 12:40:45 +010052
53#include "sound/compress_params.h"
54
Christopher N. Hesse297a6362017-01-28 12:40:45 +010055
56/* TODO: the following PCM device profiles could be read from a config file */
57static struct pcm_device_profile pcm_device_playback = {
58 .config = {
59 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
60 .rate = PLAYBACK_DEFAULT_SAMPLING_RATE,
61 .period_size = PLAYBACK_PERIOD_SIZE,
62 .period_count = PLAYBACK_PERIOD_COUNT,
63 .format = PCM_FORMAT_S16_LE,
64 .start_threshold = PLAYBACK_START_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
65 .stop_threshold = PLAYBACK_STOP_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
66 .silence_threshold = 0,
67 .silence_size = UINT_MAX,
68 .avail_min = PLAYBACK_AVAILABLE_MIN,
69 },
70 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010071 .id = SOUND_PLAYBACK_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010072 .type = PCM_PLAYBACK,
73 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010074 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010075};
76
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010077static struct pcm_device_profile pcm_device_deep_buffer = {
78 .config = {
79 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
80 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
81 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
82 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
83 .format = PCM_FORMAT_S16_LE,
84 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
85 .stop_threshold = INT_MAX,
86 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
87 },
88 .card = SOUND_CARD,
89 .id = SOUND_DEEP_BUFFER_DEVICE,
90 .type = PCM_PLAYBACK,
91 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010092 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010093};
94
Christopher N. Hesse297a6362017-01-28 12:40:45 +010095static struct pcm_device_profile pcm_device_capture = {
96 .config = {
97 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
98 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
99 .period_size = CAPTURE_PERIOD_SIZE,
100 .period_count = CAPTURE_PERIOD_COUNT,
101 .format = PCM_FORMAT_S16_LE,
102 .start_threshold = CAPTURE_START_THRESHOLD,
103 .stop_threshold = 0,
104 .silence_threshold = 0,
105 .avail_min = 0,
106 },
107 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100108 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100109 .type = PCM_CAPTURE,
110 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
111};
112
113static struct pcm_device_profile pcm_device_capture_low_latency = {
114 .config = {
115 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
116 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
117 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
118 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
119 .format = PCM_FORMAT_S16_LE,
120 .start_threshold = CAPTURE_START_THRESHOLD,
121 .stop_threshold = 0,
122 .silence_threshold = 0,
123 .avail_min = 0,
124 },
125 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100126 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100127 .type = PCM_CAPTURE_LOW_LATENCY,
128 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
129};
130
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100131#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100132static struct pcm_device_profile pcm_device_capture_loopback_aec = {
133 .config = {
134 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
135 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
136 .period_size = CAPTURE_PERIOD_SIZE,
137 .period_count = CAPTURE_PERIOD_COUNT,
138 .format = PCM_FORMAT_S16_LE,
139 .start_threshold = CAPTURE_START_THRESHOLD,
140 .stop_threshold = 0,
141 .silence_threshold = 0,
142 .avail_min = 0,
143 },
144 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100145 .id = SOUND_CAPTURE_LOOPBACK_AEC_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100146 .type = PCM_CAPTURE,
147 .devices = SND_DEVICE_IN_LOOPBACK_AEC,
148};
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100149#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100150
151static struct pcm_device_profile pcm_device_playback_sco = {
152 .config = {
153 .channels = SCO_DEFAULT_CHANNEL_COUNT,
154 .rate = SCO_DEFAULT_SAMPLING_RATE,
155 .period_size = SCO_PERIOD_SIZE,
156 .period_count = SCO_PERIOD_COUNT,
157 .format = PCM_FORMAT_S16_LE,
158 .start_threshold = SCO_START_THRESHOLD,
159 .stop_threshold = SCO_STOP_THRESHOLD,
160 .silence_threshold = 0,
161 .avail_min = SCO_AVAILABLE_MIN,
162 },
163 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100164 .id = SOUND_PLAYBACK_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100165 .type = PCM_PLAYBACK,
166 .devices =
167 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
168 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
169};
170
171static struct pcm_device_profile pcm_device_capture_sco = {
172 .config = {
173 .channels = SCO_DEFAULT_CHANNEL_COUNT,
174 .rate = SCO_DEFAULT_SAMPLING_RATE,
175 .period_size = SCO_PERIOD_SIZE,
176 .period_count = SCO_PERIOD_COUNT,
177 .format = PCM_FORMAT_S16_LE,
178 .start_threshold = CAPTURE_START_THRESHOLD,
179 .stop_threshold = 0,
180 .silence_threshold = 0,
181 .avail_min = 0,
182 },
183 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100184 .id = SOUND_CAPTURE_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100185 .type = PCM_CAPTURE,
186 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
187};
188
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100189#ifdef SOUND_CAPTURE_HOTWORD_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100190static struct pcm_device_profile pcm_device_hotword_streaming = {
191 .config = {
192 .channels = 1,
193 .rate = 16000,
194 .period_size = CAPTURE_PERIOD_SIZE,
195 .period_count = CAPTURE_PERIOD_COUNT,
196 .format = PCM_FORMAT_S16_LE,
197 .start_threshold = CAPTURE_START_THRESHOLD,
198 .stop_threshold = 0,
199 .silence_threshold = 0,
200 .avail_min = 0,
201 },
202 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100203 .id = SOUND_CAPTURE_HOTWORD_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100204 .type = PCM_HOTWORD_STREAMING,
205 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC
206};
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100207#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100208
209static struct pcm_device_profile * const pcm_devices[] = {
210 &pcm_device_playback,
211 &pcm_device_capture,
212 &pcm_device_capture_low_latency,
213 &pcm_device_playback_sco,
214 &pcm_device_capture_sco,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100215#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100216 &pcm_device_capture_loopback_aec,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100217#endif
218#ifdef SOUND_CAPTURE_HOTWORD_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100219 &pcm_device_hotword_streaming,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100220#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100221 NULL,
222};
223
224static const char * const use_case_table[AUDIO_USECASE_MAX] = {
225 [USECASE_AUDIO_PLAYBACK] = "playback",
226 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
227 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
Andreas Schneiderdf6fc8a2017-02-14 11:38:41 +0100228 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback deep-buffer",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100229 [USECASE_AUDIO_CAPTURE] = "capture",
230 [USECASE_AUDIO_CAPTURE_HOTWORD] = "capture-hotword",
231 [USECASE_VOICE_CALL] = "voice-call",
232};
233
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100234#define STRING_TO_ENUM(string) { #string, string }
235
236static unsigned int audio_device_ref_count;
237
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100238struct string_to_enum {
239 const char *name;
240 uint32_t value;
241};
242
243static const struct string_to_enum out_channels_name_to_enum_table[] = {
244 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
245 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
246 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
247};
248
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200249static struct audio_device *adev = NULL;
250
251static amplifier_device_t * get_amplifier_device(void)
252{
253 if (adev)
254 return adev->amp;
255
256 return NULL;
257}
258
259static int amplifier_open(void)
260{
261 int rc;
262 amplifier_module_t *module;
263
264 rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
265 (const hw_module_t **) &module);
266 if (rc) {
267 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
268 __func__, strerror(-rc));
269 return -ENODEV;
270 }
271
272 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
273 if (rc) {
274 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
275 __func__, strerror(-rc));
276 return -ENODEV;
277 }
278
279 return 0;
280}
281
282static int amplifier_set_input_devices(uint32_t devices)
283{
284 amplifier_device_t *amp = get_amplifier_device();
285 if (amp && amp->set_input_devices)
286 return amp->set_input_devices(amp, devices);
287
288 return 0;
289}
290
291static int amplifier_set_output_devices(uint32_t devices)
292{
293 amplifier_device_t *amp = get_amplifier_device();
294 if (amp && amp->set_output_devices)
295 return amp->set_output_devices(amp, devices);
296
297 return 0;
298}
299
300static int amplifier_enable_devices(uint32_t devices, bool enable)
301{
302 amplifier_device_t *amp = get_amplifier_device();
303 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
304 devices < SND_DEVICE_OUT_END;
305
306 if (amp && amp->enable_output_devices && is_output)
307 return amp->enable_output_devices(amp, devices, enable);
308
309 if (amp && amp->enable_input_devices && !is_output)
310 return amp->enable_input_devices(amp, devices, enable);
311
312 return 0;
313}
314
315static int amplifier_set_mode(audio_mode_t mode)
316{
317 amplifier_device_t *amp = get_amplifier_device();
318 if (amp && amp->set_mode)
319 return amp->set_mode(amp, mode);
320
321 return 0;
322}
323
324static int amplifier_output_stream_start(struct audio_stream_out *stream,
325 bool offload)
326{
327 amplifier_device_t *amp = get_amplifier_device();
328 if (amp && amp->output_stream_start)
329 return amp->output_stream_start(amp, stream, offload);
330
331 return 0;
332}
333
334static int amplifier_input_stream_start(struct audio_stream_in *stream)
335{
336 amplifier_device_t *amp = get_amplifier_device();
337 if (amp && amp->input_stream_start)
338 return amp->input_stream_start(amp, stream);
339
340 return 0;
341}
342
343static int amplifier_output_stream_standby(struct audio_stream_out *stream)
344{
345 amplifier_device_t *amp = get_amplifier_device();
346 if (amp && amp->output_stream_standby)
347 return amp->output_stream_standby(amp, stream);
348
349 return 0;
350}
351
352static int amplifier_input_stream_standby(struct audio_stream_in *stream)
353{
354 amplifier_device_t *amp = get_amplifier_device();
355 if (amp && amp->input_stream_standby)
356 return amp->input_stream_standby(amp, stream);
357
358 return 0;
359}
360
361static int amplifier_set_parameters(struct str_parms *parms)
362{
363 amplifier_device_t *amp = get_amplifier_device();
364 if (amp && amp->set_parameters)
365 return amp->set_parameters(amp, parms);
366
367 return 0;
368}
369
370static int amplifier_close(void)
371{
372 amplifier_device_t *amp = get_amplifier_device();
373 if (amp)
374 amplifier_device_close(amp);
375
376 return 0;
377}
378
Andreas Schneider759368f2017-02-02 16:11:14 +0100379struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
380 struct timespec ret;
381 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100382
383 if (time0.tv_nsec > time1.tv_nsec) {
384 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
385 time0.tv_nsec -= (long int) (1E9 * xsec);
386 time0.tv_sec += xsec;
387 }
388
389 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
390 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
391 time0.tv_nsec += (long int) (1E9 * xsec);
392 time0.tv_sec -= xsec;
393 }
394
Paul Keithf114e2e2017-02-14 20:41:33 -0600395 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
396 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100397
398 return ret;
399}
400
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100401static bool is_supported_format(audio_format_t format)
402{
403 if (format == AUDIO_FORMAT_MP3 ||
404 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
405 return true;
406
407 return false;
408}
409
410static int get_snd_codec_id(audio_format_t format)
411{
412 int id = 0;
413
414 switch (format & AUDIO_FORMAT_MAIN_MASK) {
415 case AUDIO_FORMAT_MP3:
416 id = SND_AUDIOCODEC_MP3;
417 break;
418 case AUDIO_FORMAT_AAC:
419 id = SND_AUDIOCODEC_AAC;
420 break;
421 default:
422 ALOGE("%s: Unsupported audio format", __func__);
423 }
424
425 return id;
426}
427
428/* Array to store sound devices */
429static const char * const device_table[SND_DEVICE_MAX] = {
430 [SND_DEVICE_NONE] = "none",
431 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100432 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100433 [SND_DEVICE_OUT_SPEAKER] = "speaker",
434 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
435 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100436 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100437 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100438 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100439 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100440 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100441 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100442 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
443 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100444 [SND_DEVICE_OUT_HDMI] = "hdmi",
445 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
446 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100447
448 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100449 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100450 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
451 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100452 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100453 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
454 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100455 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
456 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100457 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100458 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100459 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100460 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100461 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100462 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
463 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100464 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
465 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
466 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100467 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
468 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100469 [SND_DEVICE_IN_LOOPBACK_AEC] = "loopback-aec",
470};
471
472static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
473{
474 struct mixer_card *mixer_card;
475 struct listnode *node;
476
477 list_for_each(node, &adev->mixer_list) {
478 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
479 if (mixer_card->card == card)
480 return mixer_card;
481 }
482 return NULL;
483}
484
485static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
486{
487 struct mixer_card *mixer_card;
488 struct listnode *node;
489
490 list_for_each(node, &usecase->mixer_list) {
491 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
492 if (mixer_card->card == card)
493 return mixer_card;
494 }
495 return NULL;
496}
497
498static void free_mixer_list(struct audio_device *adev)
499{
500 struct mixer_card *mixer_card;
501 struct listnode *node;
502 struct listnode *next;
503
504 list_for_each_safe(node, next, &adev->mixer_list) {
505 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
506 list_remove(node);
507 audio_route_free(mixer_card->audio_route);
508 free(mixer_card);
509 }
510}
511
512static int mixer_init(struct audio_device *adev)
513{
514 int i;
515 int card;
516 int retry_num;
517 struct mixer *mixer;
518 struct audio_route *audio_route;
519 char mixer_path[PATH_MAX];
520 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100521 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100522
523 list_init(&adev->mixer_list);
524
525 for (i = 0; pcm_devices[i] != NULL; i++) {
526 card = pcm_devices[i]->card;
527 if (adev_get_mixer_for_card(adev, card) == NULL) {
528 retry_num = 0;
529 do {
530 mixer = mixer_open(card);
531 if (mixer == NULL) {
532 if (++retry_num > RETRY_NUMBER) {
533 ALOGE("%s unable to open the mixer for--card %d, aborting.",
534 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100535 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100536 goto error;
537 }
538 usleep(RETRY_US);
539 }
540 } while (mixer == NULL);
541
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100542 sprintf(mixer_path, "/vendor/etc/mixer_paths_%d.xml", card);
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100543 if (access(mixer_path, F_OK) == -1) {
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100544 ALOGW("%s: Failed to open mixer paths from %s, retrying with legacy location",
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100545 __func__, mixer_path);
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100546 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
547 if (access(mixer_path, F_OK) == -1) {
548 ALOGE("%s: Failed to load a mixer paths configuration, your system will crash",
549 __func__);
550 }
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100551 }
552
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100553 audio_route = audio_route_init(card, mixer_path);
554 if (!audio_route) {
555 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
556 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100557 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100558 goto error;
559 }
560 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100561 if (mixer_card == NULL) {
562 ret = -ENOMEM;
563 goto error;
564 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100565 mixer_card->card = card;
566 mixer_card->mixer = mixer;
567 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100568
569 /* Do not sleep on first enable_snd_device() */
570 mixer_card->dsp_poweroff_time.tv_sec = 1;
571 mixer_card->dsp_poweroff_time.tv_nsec = 0;
572
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100573 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
574 }
575 }
576
577 return 0;
578
579error:
580 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100581 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100582}
583
584static const char *get_snd_device_name(snd_device_t snd_device)
585{
586 const char *name = NULL;
587
Andreas Schneideradb788d2017-02-13 15:19:36 +0100588 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100589 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100590 name = device_table[snd_device];
591
592 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
593
594 return name;
595}
596
597static const char *get_snd_device_display_name(snd_device_t snd_device)
598{
599 const char *name = get_snd_device_name(snd_device);
600
601 if (name == NULL)
602 name = "SND DEVICE NOT FOUND";
603
604 return name;
605}
606
607static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
608{
609 int i;
610
611 devices &= ~AUDIO_DEVICE_BIT_IN;
612 for (i = 0; pcm_devices[i] != NULL; i++) {
613 if ((pcm_devices[i]->type == uc_type) &&
614 (devices & pcm_devices[i]->devices))
615 break;
616 }
617 return pcm_devices[i];
618}
619
620static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
621 audio_usecase_t uc_id)
622{
623 struct audio_usecase *usecase;
624 struct listnode *node;
625
626 list_for_each(node, &adev->usecase_list) {
627 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
628 if (usecase->id == uc_id)
629 return usecase;
630 }
631 return NULL;
632}
633
634static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
635 usecase_type_t type)
636{
637 struct audio_usecase *usecase;
638 struct listnode *node;
639
640 list_for_each(node, &adev->usecase_list) {
641 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
642 if (usecase->type & type)
643 return usecase;
644 }
645 return NULL;
646}
647
648/* always called with adev lock held */
649static int set_voice_volume_l(struct audio_device *adev, float volume)
650{
651 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100652
653 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100654 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100655 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100656
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100657 return err;
658}
659
660
661static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
662{
663
664 audio_mode_t mode = adev->mode;
665 snd_device_t snd_device = SND_DEVICE_NONE;
666
667 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
668 if (devices == AUDIO_DEVICE_NONE ||
669 devices & AUDIO_DEVICE_BIT_IN) {
670 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
671 goto exit;
672 }
673
674 if (mode == AUDIO_MODE_IN_CALL) {
675 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
676 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100677 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300678 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100679 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100680 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
681 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
682 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100683 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100684 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100685
686 if (voice_session_uses_wideband(adev->voice.session)) {
687 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
688 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
689 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300690 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100691 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100692 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
693 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
694 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
695 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
696 }
697 }
698
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100699 if (snd_device != SND_DEVICE_NONE) {
700 goto exit;
701 }
702 }
703
704 if (popcount(devices) == 2) {
705 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
706 AUDIO_DEVICE_OUT_SPEAKER)) {
707 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
708 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
709 AUDIO_DEVICE_OUT_SPEAKER)) {
710 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
711 } else {
712 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
713 goto exit;
714 }
715 if (snd_device != SND_DEVICE_NONE) {
716 goto exit;
717 }
718 }
719
720 if (popcount(devices) != 1) {
721 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
722 goto exit;
723 }
724
725 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
726 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
727 snd_device = SND_DEVICE_OUT_HEADPHONES;
728 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
729 snd_device = SND_DEVICE_OUT_SPEAKER;
730 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
731 snd_device = SND_DEVICE_OUT_BT_SCO;
732 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100733 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100734 } else {
735 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
736 }
737exit:
738 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
739 return snd_device;
740}
741
742static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
743{
744 audio_source_t source;
745 audio_mode_t mode = adev->mode;
746 audio_devices_t in_device;
747 audio_channel_mask_t channel_mask;
748 snd_device_t snd_device = SND_DEVICE_NONE;
749 struct stream_in *active_input = NULL;
750 struct audio_usecase *usecase;
751
752 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
753 if (usecase != NULL) {
754 active_input = (struct stream_in *)usecase->stream;
755 }
756 source = (active_input == NULL) ?
757 AUDIO_SOURCE_DEFAULT : active_input->source;
758
Andreas Schneider757e2d82017-02-10 19:28:35 +0100759 in_device = (active_input == NULL) ?
760 AUDIO_DEVICE_NONE :
761 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100762 channel_mask = (active_input == NULL) ?
763 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
764
765 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
766 __func__, out_device, in_device);
767 if (mode == AUDIO_MODE_IN_CALL) {
768 if (out_device == AUDIO_DEVICE_NONE) {
769 ALOGE("%s: No output device set for voice call", __func__);
770 goto exit;
771 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100772
Andreas Schneider82f32482017-02-06 09:00:48 +0100773 snd_device = SND_DEVICE_IN_VOICE_MIC;
774 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100775 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100776 }
777
778 if (voice_session_uses_twomic(adev->voice.session)) {
779 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
780 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
781 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
782 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
783 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
784 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100785 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100786
787 if (voice_session_uses_wideband(adev->voice.session)) {
788 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
789 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
790 }
791
792 if (voice_session_uses_twomic(adev->voice.session)) {
793 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
794 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
795 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
796 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
797 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
798 }
799 }
800 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100801
802 /* BT SCO */
803 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
804 snd_device = SND_DEVICE_IN_VOICE_MIC;
805
806 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300807 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100808 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300809 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100810 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300811 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100812 } else if (voice_session_uses_twomic(adev->voice.session)) {
813 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
814 }
815 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100816 } else if (source == AUDIO_SOURCE_CAMCORDER) {
817 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
818 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
819 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
820 }
821 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
822 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100823 if (snd_device == SND_DEVICE_NONE) {
824 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
825 }
826 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
827 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
828 }
829 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
830 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
831 in_device = AUDIO_DEVICE_IN_BACK_MIC;
832 if (active_input) {
833 if (active_input->enable_aec) {
834 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
835 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
836 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
837 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
838 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
839 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100840 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100841 }
842 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
843 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
844 }
845 }
846 /* TODO: set echo reference */
847 }
848 } else if (source == AUDIO_SOURCE_DEFAULT) {
849 goto exit;
850 }
851
852
853 if (snd_device != SND_DEVICE_NONE) {
854 goto exit;
855 }
856
857 if (in_device != AUDIO_DEVICE_NONE &&
858 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
859 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
860 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100861 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100862 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
863 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
864 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
865 snd_device = SND_DEVICE_IN_HEADSET_MIC;
866 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
867 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
868 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
869 snd_device = SND_DEVICE_IN_HDMI_MIC;
870 } else {
871 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100872 ALOGW("%s: Using default earpiece-mic", __func__);
873 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100874 }
875 } else {
876 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100877 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100878 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
879 snd_device = SND_DEVICE_IN_HEADSET_MIC;
880 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
881 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
882 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100883 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100884 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
885 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
886 } else {
887 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100888 ALOGW("%s: Using default earpiece-mic", __func__);
889 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100890 }
891 }
892exit:
893 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
894 return snd_device;
895}
896
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100897#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100898static int set_hdmi_channels(struct audio_device *adev, int channel_count)
899{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100900 (void)adev;
901 (void)channel_count;
902 /* TODO */
903
904 return 0;
905}
906
907static int edid_get_max_channels(struct audio_device *adev)
908{
909 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100910 (void)adev;
911
912 /* TODO */
913 return max_channels;
914}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100915#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100916
917/* Delay in Us */
918static int64_t render_latency(audio_usecase_t usecase)
919{
920 (void)usecase;
921 /* TODO */
922 return 0;
923}
924
925static int enable_snd_device(struct audio_device *adev,
926 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100927 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100928{
929 struct mixer_card *mixer_card;
930 struct listnode *node;
931 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100932#ifdef DSP_POWEROFF_DELAY
933 struct timespec activation_time;
934 struct timespec elapsed_time;
935#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100936
937 if (snd_device_name == NULL)
938 return -EINVAL;
939
940 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
941 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100942 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
943 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100944 return 0;
945 }
946 adev->snd_dev_ref_cnt[snd_device]++;
947 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
948 ALOGV("%s: snd_device(%d: %s) is already active",
949 __func__, snd_device, snd_device_name);
950 return 0;
951 }
952
953 ALOGV("%s: snd_device(%d: %s)", __func__,
954 snd_device, snd_device_name);
955
956 list_for_each(node, &uc_info->mixer_list) {
957 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100958
959#ifdef DSP_POWEROFF_DELAY
960 clock_gettime(CLOCK_MONOTONIC, &activation_time);
961
Andreas Schneider58735a92017-02-13 16:48:17 +0100962 elapsed_time = time_spec_diff(activation_time,
963 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100964 if (elapsed_time.tv_sec == 0) {
965 long elapsed_usec = elapsed_time.tv_nsec / 1000;
966
967 if (elapsed_usec < DSP_POWEROFF_DELAY) {
968 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
969 }
970 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100971#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200972
973 amplifier_enable_devices(snd_device, true);
974
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100975 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100976 }
977
978 return 0;
979}
980
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100981int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100982 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100983 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100984{
985 struct mixer_card *mixer_card;
986 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100987 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100988 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100989 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100990
991 if (snd_device_name == NULL)
992 return -EINVAL;
993
994 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
995 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100996 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
997 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100998 return 0;
999 }
1000
1001 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
1002 ALOGE("%s: device ref cnt is already 0", __func__);
1003 return -EINVAL;
1004 }
1005 adev->snd_dev_ref_cnt[snd_device]--;
1006 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
1007 ALOGV("%s: snd_device(%d: %s)", __func__,
1008 snd_device, snd_device_name);
1009 list_for_each(node, &uc_info->mixer_list) {
1010 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001011 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +01001012 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +01001013 /*
1014 * Cycle the rx device to eliminate routing conflicts.
1015 * This prevents issues when an input route shares mixer controls with an output
1016 * route.
1017 */
1018 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001019 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +01001020 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001021
1022 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +01001023#ifdef DSP_POWEROFF_DELAY
1024 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
1025#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001026 }
1027 }
1028 return 0;
1029}
1030
1031static int select_devices(struct audio_device *adev,
1032 audio_usecase_t uc_id)
1033{
1034 snd_device_t out_snd_device = SND_DEVICE_NONE;
1035 snd_device_t in_snd_device = SND_DEVICE_NONE;
1036 struct audio_usecase *usecase = NULL;
1037 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001038 struct stream_in *active_input = NULL;
1039 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001040
1041 ALOGV("%s: usecase(%d)", __func__, uc_id);
1042
1043 if (uc_id == USECASE_AUDIO_CAPTURE_HOTWORD)
1044 return 0;
1045
1046 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1047 if (usecase != NULL) {
1048 active_input = (struct stream_in *)usecase->stream;
1049 }
1050
1051 usecase = get_usecase_from_id(adev, uc_id);
1052 if (usecase == NULL) {
1053 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1054 return -EINVAL;
1055 }
1056 active_out = (struct stream_out *)usecase->stream;
1057
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001058
1059 /*
1060 * If the voice call is active, use the sound devices of voice call usecase
1061 * so that it would not result any device switch. All the usecases will
1062 * be switched to new device when select_devices() is called for voice call
1063 * usecase.
1064 */
1065 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1066 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1067 if (vc_usecase == NULL) {
1068 ALOGE("%s: Could not find the voice call usecase", __func__);
1069 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001070 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1071 get_snd_device_display_name(vc_usecase->out_snd_device),
1072 get_snd_device_display_name(vc_usecase->in_snd_device));
1073 usecase->devices = vc_usecase->devices;
1074 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001075 }
1076 }
1077
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001078 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001079 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001080 prepare_voice_session(adev->voice.session, active_out->devices);
1081 out_snd_device = get_output_snd_device(adev, active_out->devices);
1082 in_snd_device = get_input_snd_device(adev, active_out->devices);
1083 } else if (usecase->type == PCM_PLAYBACK) {
1084 usecase->devices = active_out->devices;
1085 in_snd_device = SND_DEVICE_NONE;
1086 if (out_snd_device == SND_DEVICE_NONE) {
1087 out_snd_device = get_output_snd_device(adev, active_out->devices);
1088 if (active_out == adev->primary_output &&
1089 active_input &&
1090 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1091 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001092 }
1093 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001094 } else if (usecase->type == PCM_CAPTURE) {
1095 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1096 out_snd_device = SND_DEVICE_NONE;
1097 if (in_snd_device == SND_DEVICE_NONE) {
1098 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1099 adev->primary_output && !adev->primary_output->standby) {
1100 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1101 } else {
1102 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001103 }
1104 }
1105 }
1106
1107 if (out_snd_device == usecase->out_snd_device &&
1108 in_snd_device == usecase->in_snd_device) {
1109 return 0;
1110 }
1111
1112 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1113 out_snd_device, get_snd_device_display_name(out_snd_device),
1114 in_snd_device, get_snd_device_display_name(in_snd_device));
1115
1116
1117 /* Disable current sound devices */
1118 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001119 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001120 }
1121
1122 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001123 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001124 }
1125
1126 /* Enable new sound devices */
1127 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001128 /* We need to update the audio path if we switch the out devices */
1129 if (adev->voice.in_call) {
1130 set_voice_session_audio_path(adev->voice.session);
1131 }
1132
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001133 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001134 }
1135
1136 if (in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001137 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001138 }
1139
1140 usecase->in_snd_device = in_snd_device;
1141 usecase->out_snd_device = out_snd_device;
1142
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001143 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1144 amplifier_set_input_devices(in_snd_device);
1145 amplifier_set_output_devices(out_snd_device);
1146
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001147 return 0;
1148}
1149
1150
1151static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1152static int do_in_standby_l(struct stream_in *in);
1153
1154#ifdef PREPROCESSING_ENABLED
1155static void get_capture_reference_delay(struct stream_in *in,
1156 size_t frames __unused,
1157 struct echo_reference_buffer *buffer)
1158{
1159 ALOGVV("%s: enter:)", __func__);
1160
1161 /* read frames available in kernel driver buffer */
1162 unsigned int kernel_frames;
1163 struct timespec tstamp;
1164 long buf_delay;
1165 long kernel_delay;
1166 long delay_ns;
1167 struct pcm_device *ref_device;
1168 long rsmp_delay = 0;
1169
1170 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1171 struct pcm_device, stream_list_node);
1172
1173 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1174 buffer->time_stamp.tv_sec = 0;
1175 buffer->time_stamp.tv_nsec = 0;
1176 buffer->delay_ns = 0;
1177 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1178 return;
1179 }
1180
1181 /* adjust render time stamp with delay added by current driver buffer.
1182 * Add the duration of current frame as we want the render time of the last
1183 * sample being written. */
1184
1185 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1186
1187 buffer->time_stamp = tstamp;
1188 buffer->delay_ns = kernel_delay;
1189
1190 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1191 " delay_ns: [%d] , frames:[%zd]",
1192 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1193}
1194
1195static void get_capture_delay(struct stream_in *in,
1196 size_t frames __unused,
1197 struct echo_reference_buffer *buffer)
1198{
1199 ALOGVV("%s: enter:)", __func__);
1200 /* read frames available in kernel driver buffer */
1201 unsigned int kernel_frames;
1202 struct timespec tstamp;
1203 long buf_delay;
1204 long rsmp_delay;
1205 long kernel_delay;
1206 long delay_ns;
1207 struct pcm_device *pcm_device;
1208
1209 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1210 struct pcm_device, stream_list_node);
1211
1212 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1213 buffer->time_stamp.tv_sec = 0;
1214 buffer->time_stamp.tv_nsec = 0;
1215 buffer->delay_ns = 0;
1216 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1217 return;
1218 }
1219
1220 /* read frames available in audio HAL input buffer
1221 * add number of frames being read as we want the capture time of first sample
1222 * in current buffer */
1223 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1224 * at requested sampling rate */
1225 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1226 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1227
1228 /* add delay introduced by resampler */
1229 rsmp_delay = 0;
1230 if (in->resampler) {
1231 rsmp_delay = in->resampler->delay_ns(in->resampler);
1232 }
1233
1234 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1235
1236 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1237
1238 buffer->time_stamp = tstamp;
1239 buffer->delay_ns = delay_ns;
1240 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1241 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1242 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1243 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1244 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1245 in->read_buf_frames, in->proc_buf_frames, frames);
1246}
1247
1248static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1249{
1250 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1251 struct echo_reference_buffer b;
1252 b.delay_ns = 0;
1253 struct pcm_device *pcm_device;
1254
1255 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1256 struct pcm_device, stream_list_node);
1257
1258 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1259 "b.frame_count = [%zd]",
1260 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1261 if (in->ref_buf_frames < frames) {
1262 if (in->ref_buf_size < frames) {
1263 in->ref_buf_size = frames;
1264 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1265 ALOG_ASSERT((in->ref_buf != NULL),
1266 "update_echo_reference() failed to reallocate ref_buf");
1267 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1268 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1269 }
1270 b.frame_count = frames - in->ref_buf_frames;
1271 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1272
1273 get_capture_delay(in, frames, &b);
1274
1275 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1276 {
1277 in->ref_buf_frames += b.frame_count;
1278 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1279 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1280 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1281 }
1282 } else
1283 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1284 return b.delay_ns;
1285}
1286
1287static int set_preprocessor_param(effect_handle_t handle,
1288 effect_param_t *param)
1289{
1290 uint32_t size = sizeof(int);
1291 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1292 param->vsize;
1293
1294 int status = (*handle)->command(handle,
1295 EFFECT_CMD_SET_PARAM,
1296 sizeof (effect_param_t) + psize,
1297 param,
1298 &size,
1299 &param->status);
1300 if (status == 0)
1301 status = param->status;
1302
1303 return status;
1304}
1305
1306static int set_preprocessor_echo_delay(effect_handle_t handle,
1307 int32_t delay_us)
1308{
1309 struct {
1310 effect_param_t param;
1311 uint32_t data_0;
1312 int32_t data_1;
1313 } buf;
1314 memset(&buf, 0, sizeof(buf));
1315
1316 buf.param.psize = sizeof(uint32_t);
1317 buf.param.vsize = sizeof(uint32_t);
1318 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1319 buf.data_1 = delay_us;
1320
1321 return set_preprocessor_param(handle, &buf.param);
1322}
1323
1324static void push_echo_reference(struct stream_in *in, size_t frames)
1325{
1326 ALOGVV("%s: enter:)", __func__);
1327 /* read frames from echo reference buffer and update echo delay
1328 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1329
1330 int32_t delay_us = update_echo_reference(in, frames)/1000;
1331 int32_t size_in_bytes = 0;
1332 int i;
1333 audio_buffer_t buf;
1334
1335 if (in->ref_buf_frames < frames)
1336 frames = in->ref_buf_frames;
1337
1338 buf.frameCount = frames;
1339 buf.raw = in->ref_buf;
1340
1341 for (i = 0; i < in->num_preprocessors; i++) {
1342 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1343 continue;
1344 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1345 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1346 &buf,
1347 NULL);
1348 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1349 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1350 }
1351
1352 in->ref_buf_frames -= buf.frameCount;
1353 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1354 __func__, in->ref_buf_frames, in->config.channels);
1355 if (in->ref_buf_frames) {
1356 memcpy(in->ref_buf,
1357 in->ref_buf + buf.frameCount * in->config.channels,
1358 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1359 }
1360}
1361
1362static void put_echo_reference(struct audio_device *adev,
1363 struct echo_reference_itfe *reference)
1364{
1365 ALOGV("%s: enter:)", __func__);
1366 int32_t prev_generation = adev->echo_reference_generation;
1367 struct stream_out *out = adev->primary_output;
1368
1369 if (adev->echo_reference != NULL &&
1370 reference == adev->echo_reference) {
1371 /* echo reference is taken from the low latency output stream used
1372 * for voice use cases */
1373 adev->echo_reference = NULL;
1374 android_atomic_inc(&adev->echo_reference_generation);
1375 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1376 // if the primary output is in standby or did not pick the echo reference yet
1377 // we can safely get rid of it here.
1378 // otherwise, out_write() or out_standby() will detect the change in echo reference
1379 // generation and release the echo reference owned by the stream.
1380 if ((out->echo_reference_generation != prev_generation) || out->standby)
1381 release_echo_reference(reference);
1382 } else {
1383 release_echo_reference(reference);
1384 }
1385 ALOGV("release_echo_reference");
1386 }
1387}
1388
1389static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1390 audio_format_t format __unused,
1391 uint32_t channel_count,
1392 uint32_t sampling_rate)
1393{
1394 ALOGV("%s: enter:)", __func__);
1395 put_echo_reference(adev, adev->echo_reference);
1396 /* echo reference is taken from the low latency output stream used
1397 * for voice use cases */
1398 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1399 !adev->primary_output->standby) {
1400 struct audio_stream *stream =
1401 &adev->primary_output->stream.common;
1402 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1403 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1404 ALOGV("Calling create_echo_reference");
1405 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1406 channel_count,
1407 sampling_rate,
1408 AUDIO_FORMAT_PCM_16_BIT,
1409 wr_channel_count,
1410 wr_sampling_rate,
1411 &adev->echo_reference);
1412 if (status == 0)
1413 android_atomic_inc(&adev->echo_reference_generation);
1414 }
1415 return adev->echo_reference;
1416}
1417
1418#ifdef HW_AEC_LOOPBACK
1419static int get_hw_echo_reference(struct stream_in *in)
1420{
1421 struct pcm_device_profile *ref_pcm_profile;
1422 struct pcm_device *ref_device;
1423 struct audio_device *adev = in->dev;
1424
1425 in->hw_echo_reference = false;
1426
1427 if (adev->primary_output!= NULL &&
1428 !adev->primary_output->standby &&
1429 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1430 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1431 struct audio_stream *stream = &adev->primary_output->stream.common;
1432
1433 // TODO: currently there is no low latency mode for aec reference.
1434 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1435 if (ref_pcm_profile == NULL) {
1436 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1437 __func__, pcm_device_capture_loopback_aec.devices);
1438 return -EINVAL;
1439 }
1440
1441 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001442 if (ref_device == NULL) {
1443 return -ENOMEM;
1444 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001445 ref_device->pcm_profile = ref_pcm_profile;
1446
1447 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1448 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1449
1450 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1451 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1452 pcm_close(ref_device->pcm);
1453 ref_device->pcm = NULL;
1454 return -EIO;
1455 }
1456 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1457
1458 in->hw_echo_reference = true;
1459
1460 ALOGV("%s: hw_echo_reference is true", __func__);
1461 }
1462
1463 return 0;
1464}
1465#endif
1466
1467static int get_playback_delay(struct stream_out *out,
1468 size_t frames,
1469 struct echo_reference_buffer *buffer)
1470{
1471 unsigned int kernel_frames;
1472 int status;
1473 int primary_pcm = 0;
1474 struct pcm_device *pcm_device;
1475
1476 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1477 struct pcm_device, stream_list_node);
1478
1479 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1480 if (status < 0) {
1481 buffer->time_stamp.tv_sec = 0;
1482 buffer->time_stamp.tv_nsec = 0;
1483 buffer->delay_ns = 0;
1484 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1485 "setting playbackTimestamp to 0");
1486 return status;
1487 }
1488
1489 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1490
1491 /* adjust render time stamp with delay added by current driver buffer.
1492 * Add the duration of current frame as we want the render time of the last
1493 * sample being written. */
1494 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1495 out->config.rate);
1496 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1497 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1498
1499 return 0;
1500}
1501
1502#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1503 do { \
1504 if (fct_status != 0) \
1505 status = fct_status; \
1506 else if (cmd_status != 0) \
1507 status = cmd_status; \
1508 } while(0)
1509
1510static int in_configure_reverse(struct stream_in *in)
1511{
1512 int32_t cmd_status;
1513 uint32_t size = sizeof(int);
1514 effect_config_t config;
1515 int32_t status = 0;
1516 int32_t fct_status = 0;
1517 int i;
1518 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1519 if (in->num_preprocessors > 0) {
1520 config.inputCfg.channels = in->main_channels;
1521 config.outputCfg.channels = in->main_channels;
1522 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1523 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1524 config.inputCfg.samplingRate = in->requested_rate;
1525 config.outputCfg.samplingRate = in->requested_rate;
1526 config.inputCfg.mask =
1527 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1528 config.outputCfg.mask =
1529 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1530
1531 for (i = 0; i < in->num_preprocessors; i++)
1532 {
1533 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1534 continue;
1535 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1536 in->preprocessors[i].effect_itfe,
1537 EFFECT_CMD_SET_CONFIG_REVERSE,
1538 sizeof(effect_config_t),
1539 &config,
1540 &size,
1541 &cmd_status);
1542 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1543 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1544 }
1545 }
1546 return status;
1547}
1548
1549#define MAX_NUM_CHANNEL_CONFIGS 10
1550
1551static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1552 struct effect_info_s *effect_info)
1553{
1554 /* size and format of the cmd are defined in hardware/audio_effect.h */
1555 effect_handle_t effect = effect_info->effect_itfe;
1556 uint32_t cmd_size = 2 * sizeof(uint32_t);
1557 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1558 /* reply = status + number of configs (n) + n x channel_config_t */
1559 uint32_t reply_size =
1560 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1561 int32_t reply[reply_size];
1562 int32_t cmd_status;
1563
1564 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1565 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1566 ALOG_ASSERT((effect_info->channel_configs == NULL),
1567 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1568
1569 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1570 * This error will be interpreted as if the effect supports the main_channels but does not
1571 * support any aux_channels */
1572 cmd_status = (*effect)->command(effect,
1573 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1574 cmd_size,
1575 (void*)&cmd,
1576 &reply_size,
1577 (void*)&reply);
1578
1579 if (cmd_status != 0) {
1580 ALOGV("in_read_audio_effect_channel_configs(): "
1581 "fx->command returned %d", cmd_status);
1582 return;
1583 }
1584
1585 if (reply[0] != 0) {
1586 ALOGW("in_read_audio_effect_channel_configs(): "
1587 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1588 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1589 return;
1590 }
1591
1592 /* the feature is not supported */
1593 ALOGV("in_read_audio_effect_channel_configs()(): "
1594 "Feature supported and adding %d channel configs to the list", reply[1]);
1595 effect_info->num_channel_configs = reply[1];
1596 effect_info->channel_configs =
1597 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1598 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1599}
1600
1601
1602#define NUM_IN_AUX_CNL_CONFIGS 2
1603static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1604 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1605 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1606};
1607static uint32_t in_get_aux_channels(struct stream_in *in)
1608{
1609 int i;
1610 channel_config_t new_chcfg = {0, 0};
1611
1612 if (in->num_preprocessors == 0)
1613 return 0;
1614
1615 /* do not enable dual mic configurations when capturing from other microphones than
1616 * main or sub */
1617 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1618 return 0;
1619
1620 /* retain most complex aux channels configuration compatible with requested main channels and
1621 * supported by audio driver and all pre processors */
1622 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1623 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1624 if (cur_chcfg->main_channels == in->main_channels) {
1625 size_t match_cnt;
1626 size_t idx_preproc;
1627 for (idx_preproc = 0, match_cnt = 0;
1628 /* no need to continue if at least one preprocessor doesn't match */
1629 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1630 idx_preproc++) {
1631 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1632 size_t idx_chcfg;
1633
1634 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1635 if (memcmp(effect_info->channel_configs + idx_chcfg,
1636 cur_chcfg,
1637 sizeof(channel_config_t)) == 0) {
1638 match_cnt++;
1639 break;
1640 }
1641 }
1642 }
1643 /* if all preprocessors match, we have a candidate */
1644 if (match_cnt == (size_t)in->num_preprocessors) {
1645 /* retain most complex aux channels configuration */
1646 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1647 new_chcfg = *cur_chcfg;
1648 }
1649 }
1650 }
1651 }
1652
1653 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1654
1655 return new_chcfg.aux_channels;
1656}
1657
1658static int in_configure_effect_channels(effect_handle_t effect,
1659 channel_config_t *channel_config)
1660{
1661 int status = 0;
1662 int fct_status;
1663 int32_t cmd_status;
1664 uint32_t reply_size;
1665 effect_config_t config;
1666 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1667
1668 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1669 channel_config->main_channels,
1670 channel_config->aux_channels);
1671
1672 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1673 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1674 reply_size = sizeof(effect_config_t);
1675 fct_status = (*effect)->command(effect,
1676 EFFECT_CMD_GET_CONFIG,
1677 0,
1678 NULL,
1679 &reply_size,
1680 &config);
1681 if (fct_status != 0) {
1682 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1683 return fct_status;
1684 }
1685
1686 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1687 config.outputCfg.channels = config.inputCfg.channels;
1688 reply_size = sizeof(uint32_t);
1689 fct_status = (*effect)->command(effect,
1690 EFFECT_CMD_SET_CONFIG,
1691 sizeof(effect_config_t),
1692 &config,
1693 &reply_size,
1694 &cmd_status);
1695 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1696
1697 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1698 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1699 reply_size = sizeof(uint32_t);
1700 fct_status = (*effect)->command(effect,
1701 EFFECT_CMD_SET_FEATURE_CONFIG,
1702 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1703 cmd,
1704 &reply_size,
1705 &cmd_status);
1706 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1707
1708 /* some implementations need to be re-enabled after a config change */
1709 reply_size = sizeof(uint32_t);
1710 fct_status = (*effect)->command(effect,
1711 EFFECT_CMD_ENABLE,
1712 0,
1713 NULL,
1714 &reply_size,
1715 &cmd_status);
1716 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1717
1718 return status;
1719}
1720
1721static int in_reconfigure_channels(struct stream_in *in,
1722 effect_handle_t effect,
1723 channel_config_t *channel_config,
1724 bool config_changed) {
1725
1726 int status = 0;
1727
1728 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1729 config_changed, effect);
1730
1731 /* if config changed, reconfigure all previously added effects */
1732 if (config_changed) {
1733 int i;
1734 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1735 for (i = 0; i < in->num_preprocessors; i++)
1736 {
1737 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1738 channel_config);
1739 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1740 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1741 if (cur_status != 0) {
1742 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1743 "%d with channels: [%04x][%04x]",
1744 cur_status,
1745 i,
1746 channel_config->main_channels,
1747 channel_config->aux_channels);
1748 status = cur_status;
1749 }
1750 }
1751 } else if (effect != NULL && channel_config->aux_channels) {
1752 /* if aux channels config did not change but aux channels are present,
1753 * we still need to configure the effect being added */
1754 status = in_configure_effect_channels(effect, channel_config);
1755 }
1756 return status;
1757}
1758
1759static void in_update_aux_channels(struct stream_in *in,
1760 effect_handle_t effect)
1761{
1762 uint32_t aux_channels;
1763 channel_config_t channel_config;
1764 int status;
1765
1766 aux_channels = in_get_aux_channels(in);
1767
1768 channel_config.main_channels = in->main_channels;
1769 channel_config.aux_channels = aux_channels;
1770 status = in_reconfigure_channels(in,
1771 effect,
1772 &channel_config,
1773 (aux_channels != in->aux_channels));
1774
1775 if (status != 0) {
1776 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1777 /* resetting aux channels configuration */
1778 aux_channels = 0;
1779 channel_config.aux_channels = 0;
1780 in_reconfigure_channels(in, effect, &channel_config, true);
1781 }
1782 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1783 if (in->aux_channels != aux_channels) {
1784 in->aux_channels_changed = true;
1785 in->aux_channels = aux_channels;
1786 do_in_standby_l(in);
1787 }
1788}
1789#endif
1790
1791/* This function reads PCM data and:
1792 * - resample if needed
1793 * - process if pre-processors are attached
1794 * - discard unwanted channels
1795 */
1796static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1797{
1798 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001799 size_t src_channels = in->config.channels;
1800 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1801 int i;
1802 void *proc_buf_out;
1803 struct pcm_device *pcm_device;
1804 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1805#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001806 audio_buffer_t in_buf;
1807 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001808 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1809#endif
1810
1811 /* Additional channels might be added on top of main_channels:
1812 * - aux_channels (by processing effects)
1813 * - extra channels due to HW limitations
1814 * In case of additional channels, we cannot work inplace
1815 */
1816 if (has_additional_channels)
1817 proc_buf_out = in->proc_buf_out;
1818 else
1819 proc_buf_out = buffer;
1820
1821 if (list_empty(&in->pcm_dev_list)) {
1822 ALOGE("%s: pcm device list empty", __func__);
1823 return -EINVAL;
1824 }
1825
1826 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1827 struct pcm_device, stream_list_node);
1828
1829#ifdef PREPROCESSING_ENABLED
1830 if (has_processing) {
1831 /* since all the processing below is done in frames and using the config.channels
1832 * as the number of channels, no changes is required in case aux_channels are present */
1833 while (frames_wr < frames) {
1834 /* first reload enough frames at the end of process input buffer */
1835 if (in->proc_buf_frames < (size_t)frames) {
1836 ssize_t frames_rd;
1837 if (in->proc_buf_size < (size_t)frames) {
1838 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1839 in->proc_buf_size = (size_t)frames;
1840 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1841 ALOG_ASSERT((in->proc_buf_in != NULL),
1842 "process_frames() failed to reallocate proc_buf_in");
1843 if (has_additional_channels) {
1844 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1845 ALOG_ASSERT((in->proc_buf_out != NULL),
1846 "process_frames() failed to reallocate proc_buf_out");
1847 proc_buf_out = in->proc_buf_out;
1848 }
1849 }
1850 frames_rd = read_frames(in,
1851 in->proc_buf_in +
1852 in->proc_buf_frames * in->config.channels,
1853 frames - in->proc_buf_frames);
1854 if (frames_rd < 0) {
1855 /* Return error code */
1856 frames_wr = frames_rd;
1857 break;
1858 }
1859 in->proc_buf_frames += frames_rd;
1860 }
1861
1862 if (in->echo_reference != NULL) {
1863 push_echo_reference(in, in->proc_buf_frames);
1864 }
1865
1866 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1867 * the maximum number of frames to be consumed and produced by process() */
1868 in_buf.frameCount = in->proc_buf_frames;
1869 in_buf.s16 = in->proc_buf_in;
1870 out_buf.frameCount = frames - frames_wr;
1871 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1872
1873 /* FIXME: this works because of current pre processing library implementation that
1874 * does the actual process only when the last enabled effect process is called.
1875 * The generic solution is to have an output buffer for each effect and pass it as
1876 * input to the next.
1877 */
1878 for (i = 0; i < in->num_preprocessors; i++) {
1879 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1880 &in_buf,
1881 &out_buf);
1882 }
1883
1884 /* process() has updated the number of frames consumed and produced in
1885 * in_buf.frameCount and out_buf.frameCount respectively
1886 * move remaining frames to the beginning of in->proc_buf_in */
1887 in->proc_buf_frames -= in_buf.frameCount;
1888
1889 if (in->proc_buf_frames) {
1890 memcpy(in->proc_buf_in,
1891 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1892 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1893 }
1894
1895 /* if not enough frames were passed to process(), read more and retry. */
1896 if (out_buf.frameCount == 0) {
1897 ALOGW("No frames produced by preproc");
1898 continue;
1899 }
1900
1901 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1902 frames_wr += out_buf.frameCount;
1903 } else {
1904 /* The effect does not comply to the API. In theory, we should never end up here! */
1905 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1906 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1907 frames_wr = frames;
1908 }
1909 }
1910 }
1911 else
1912#endif //PREPROCESSING_ENABLED
1913 {
1914 /* No processing effects attached */
1915 if (has_additional_channels) {
1916 /* With additional channels, we cannot use original buffer */
1917 if (in->proc_buf_size < (size_t)frames) {
1918 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1919 in->proc_buf_size = (size_t)frames;
1920 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1921 ALOG_ASSERT((in->proc_buf_out != NULL),
1922 "process_frames() failed to reallocate proc_buf_out");
1923 proc_buf_out = in->proc_buf_out;
1924 }
1925 }
1926 frames_wr = read_frames(in, proc_buf_out, frames);
1927 }
1928
1929 /* Remove all additional channels that have been added on top of main_channels:
1930 * - aux_channels
1931 * - extra channels from HW due to HW limitations
1932 * Assumption is made that the channels are interleaved and that the main
1933 * channels are first. */
1934
1935 if (has_additional_channels)
1936 {
1937 int16_t* src_buffer = (int16_t *)proc_buf_out;
1938 int16_t* dst_buffer = (int16_t *)buffer;
1939
1940 if (dst_channels == 1) {
1941 for (i = frames_wr; i > 0; i--)
1942 {
1943 *dst_buffer++ = *src_buffer;
1944 src_buffer += src_channels;
1945 }
1946 } else {
1947 for (i = frames_wr; i > 0; i--)
1948 {
1949 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1950 dst_buffer += dst_channels;
1951 src_buffer += src_channels;
1952 }
1953 }
1954 }
1955
1956 return frames_wr;
1957}
1958
1959static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1960 struct resampler_buffer* buffer)
1961{
1962 struct stream_in *in;
1963 struct pcm_device *pcm_device;
1964
1965 if (buffer_provider == NULL || buffer == NULL)
1966 return -EINVAL;
1967
1968 in = (struct stream_in *)((char *)buffer_provider -
1969 offsetof(struct stream_in, buf_provider));
1970
1971 if (list_empty(&in->pcm_dev_list)) {
1972 buffer->raw = NULL;
1973 buffer->frame_count = 0;
1974 in->read_status = -ENODEV;
1975 return -ENODEV;
1976 }
1977
1978 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1979 struct pcm_device, stream_list_node);
1980
1981 if (in->read_buf_frames == 0) {
1982 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1983 if (in->read_buf_size < in->config.period_size) {
1984 in->read_buf_size = in->config.period_size;
1985 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1986 ALOG_ASSERT((in->read_buf != NULL),
1987 "get_next_buffer() failed to reallocate read_buf");
1988 }
1989
1990 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1991
1992 if (in->read_status != 0) {
1993 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1994 buffer->raw = NULL;
1995 buffer->frame_count = 0;
1996 return in->read_status;
1997 }
1998 in->read_buf_frames = in->config.period_size;
1999
2000#ifdef PREPROCESSING_ENABLED
2001#ifdef HW_AEC_LOOPBACK
2002 if (in->hw_echo_reference) {
2003 struct pcm_device *temp_device = NULL;
2004 struct pcm_device *ref_device = NULL;
2005 struct listnode *node = NULL;
2006 struct echo_reference_buffer b;
2007 size_t size_hw_ref_bytes;
2008 size_t size_hw_ref_frames;
2009 int read_status = 0;
2010
2011 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
2012 struct pcm_device, stream_list_node);
2013 list_for_each(node, &in->pcm_dev_list) {
2014 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
2015 if (temp_device->pcm_profile->id == 1) {
2016 ref_device = temp_device;
2017 break;
2018 }
2019 }
2020 if (ref_device) {
2021 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
2022 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
2023 if (in->hw_ref_buf_size < size_hw_ref_frames) {
2024 in->hw_ref_buf_size = size_hw_ref_frames;
2025 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2026 ALOG_ASSERT((in->hw_ref_buf != NULL),
2027 "get_next_buffer() failed to reallocate hw_ref_buf");
2028 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2029 in->hw_ref_buf, size_hw_ref_bytes);
2030 }
2031
2032 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2033 if (read_status != 0) {
2034 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2035 b.raw = NULL;
2036 b.frame_count = 0;
2037 }
2038 else {
2039 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2040 b.raw = (void *)in->hw_ref_buf;
2041 b.frame_count = size_hw_ref_frames;
2042 if (b.delay_ns != 0)
2043 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2044 in->echo_reference->write(in->echo_reference, &b);
2045 }
2046 }
2047 }
2048#endif // HW_AEC_LOOPBACK
2049#endif // PREPROCESSING_ENABLED
2050 }
2051
2052 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2053 in->read_buf_frames : buffer->frame_count;
2054 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2055 in->config.channels;
2056 return in->read_status;
2057}
2058
2059static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2060 struct resampler_buffer* buffer)
2061{
2062 struct stream_in *in;
2063
2064 if (buffer_provider == NULL || buffer == NULL)
2065 return;
2066
2067 in = (struct stream_in *)((char *)buffer_provider -
2068 offsetof(struct stream_in, buf_provider));
2069
2070 in->read_buf_frames -= buffer->frame_count;
2071}
2072
2073/* read_frames() reads frames from kernel driver, down samples to capture rate
2074 * if necessary and output the number of frames requested to the buffer specified */
2075static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2076{
2077 ssize_t frames_wr = 0;
2078
2079 struct pcm_device *pcm_device;
2080
2081 if (list_empty(&in->pcm_dev_list)) {
2082 ALOGE("%s: pcm device list empty", __func__);
2083 return -EINVAL;
2084 }
2085
2086 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2087 struct pcm_device, stream_list_node);
2088
2089 while (frames_wr < frames) {
2090 size_t frames_rd = frames - frames_wr;
2091 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2092 __func__,frames_rd,frames_wr,in->config.channels);
2093 if (in->resampler != NULL) {
2094 in->resampler->resample_from_provider(in->resampler,
2095 (int16_t *)((char *)buffer +
2096 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2097 &frames_rd);
2098 } else {
2099 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002100 .raw = NULL,
2101 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002102 };
2103 get_next_buffer(&in->buf_provider, &buf);
2104 if (buf.raw != NULL) {
2105 memcpy((char *)buffer +
2106 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2107 buf.raw,
2108 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2109 frames_rd = buf.frame_count;
2110 }
2111 release_buffer(&in->buf_provider, &buf);
2112 }
2113 /* in->read_status is updated by getNextBuffer() also called by
2114 * in->resampler->resample_from_provider() */
2115 if (in->read_status != 0)
2116 return in->read_status;
2117
2118 frames_wr += frames_rd;
2119 }
2120 return frames_wr;
2121}
2122
2123static int in_release_pcm_devices(struct stream_in *in)
2124{
2125 struct pcm_device *pcm_device;
2126 struct listnode *node;
2127 struct listnode *next;
2128
2129 list_for_each_safe(node, next, &in->pcm_dev_list) {
2130 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2131 list_remove(node);
2132 free(pcm_device);
2133 }
2134
2135 return 0;
2136}
2137
2138static int stop_input_stream(struct stream_in *in)
2139{
2140 struct audio_usecase *uc_info;
2141 struct audio_device *adev = in->dev;
2142
2143 adev->active_input = NULL;
2144 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2145 in->usecase, use_case_table[in->usecase]);
2146 uc_info = get_usecase_from_id(adev, in->usecase);
2147 if (uc_info == NULL) {
2148 ALOGE("%s: Could not find the usecase (%d) in the list",
2149 __func__, in->usecase);
2150 return -EINVAL;
2151 }
2152
2153 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002154 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002155
2156 list_remove(&uc_info->adev_list_node);
2157 free(uc_info);
2158
2159 if (list_empty(&in->pcm_dev_list)) {
2160 ALOGE("%s: pcm device list empty", __func__);
2161 return -EINVAL;
2162 }
2163
2164 in_release_pcm_devices(in);
2165 list_init(&in->pcm_dev_list);
2166
2167#ifdef HW_AEC_LOOPBACK
2168 if (in->hw_echo_reference)
2169 {
2170 in->hw_echo_reference = false;
2171 }
2172#endif
2173
2174 ALOGV("%s: exit", __func__);
2175 return 0;
2176}
2177
2178static int start_input_stream(struct stream_in *in)
2179{
2180 /* Enable output device and stream routing controls */
2181 int ret = 0;
2182 bool recreate_resampler = false;
2183 struct audio_usecase *uc_info;
2184 struct audio_device *adev = in->dev;
2185 struct pcm_device_profile *pcm_profile;
2186 struct pcm_device *pcm_device;
2187
2188 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2189 adev->active_input = in;
2190 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2191 if (pcm_profile == NULL) {
2192 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2193 __func__, in->usecase);
2194 ret = -EINVAL;
2195 goto error_config;
2196 }
2197
2198 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002199 if (uc_info == NULL) {
2200 ret = -ENOMEM;
2201 goto error_config;
2202 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002203 uc_info->id = in->usecase;
2204 uc_info->type = PCM_CAPTURE;
2205 uc_info->stream = (struct audio_stream *)in;
2206 uc_info->devices = in->devices;
2207 uc_info->in_snd_device = SND_DEVICE_NONE;
2208 uc_info->out_snd_device = SND_DEVICE_NONE;
2209
2210 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002211 if (pcm_device == NULL) {
2212 free(uc_info);
2213 ret = -ENOMEM;
2214 goto error_config;
2215 }
2216
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002217 pcm_device->pcm_profile = pcm_profile;
2218 list_init(&in->pcm_dev_list);
2219 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2220
2221 list_init(&uc_info->mixer_list);
2222 list_add_tail(&uc_info->mixer_list,
2223 &adev_get_mixer_for_card(adev,
2224 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2225
2226 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2227
2228 select_devices(adev, in->usecase);
2229
2230 /* Config should be updated as profile can be changed between different calls
2231 * to this function:
2232 * - Trigger resampler creation
2233 * - Config needs to be updated */
2234 if (in->config.rate != pcm_profile->config.rate) {
2235 recreate_resampler = true;
2236 }
2237 in->config = pcm_profile->config;
2238
2239#ifdef PREPROCESSING_ENABLED
2240 if (in->aux_channels_changed) {
2241 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2242 recreate_resampler = true;
2243 }
2244#endif
2245
2246 if (in->requested_rate != in->config.rate) {
2247 recreate_resampler = true;
2248 }
2249
2250 if (recreate_resampler) {
2251 if (in->resampler) {
2252 release_resampler(in->resampler);
2253 in->resampler = NULL;
2254 }
2255 in->buf_provider.get_next_buffer = get_next_buffer;
2256 in->buf_provider.release_buffer = release_buffer;
2257 ret = create_resampler(in->config.rate,
2258 in->requested_rate,
2259 in->config.channels,
2260 RESAMPLER_QUALITY_DEFAULT,
2261 &in->buf_provider,
2262 &in->resampler);
2263 }
2264
2265#ifdef PREPROCESSING_ENABLED
2266 if (in->enable_aec && in->echo_reference == NULL) {
2267 in->echo_reference = get_echo_reference(adev,
2268 AUDIO_FORMAT_PCM_16_BIT,
2269 audio_channel_count_from_in_mask(in->main_channels),
2270 in->requested_rate
2271 );
2272 }
2273
2274#ifdef HW_AEC_LOOPBACK
2275 if (in->enable_aec) {
2276 ret = get_hw_echo_reference(in);
2277 if (ret!=0)
2278 goto error_open;
2279
2280 /* force ref buffer reallocation */
2281 in->hw_ref_buf_size = 0;
2282 }
2283#endif
2284#endif
2285
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002286 if (in->dev->voice.in_call) {
2287 ALOGV("%s: in_call, not handling PCMs", __func__);
2288 goto skip_pcm_handling;
2289 }
2290
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002291 /* Open the PCM device.
2292 * The HW is limited to support only the default pcm_profile settings.
2293 * As such a change in aux_channels will not have an effect.
2294 */
2295 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2296 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2297 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2298 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2299
2300 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2301 if (!adev->sound_trigger_open_for_streaming) {
2302 ALOGE("%s: No handle to sound trigger HAL", __func__);
2303 ret = -EIO;
2304 goto error_open;
2305 }
2306 pcm_device->pcm = NULL;
2307 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2308 if (pcm_device->sound_trigger_handle <= 0) {
2309 ALOGE("%s: Failed to open DSP for streaming", __func__);
2310 ret = -EIO;
2311 goto error_open;
2312 }
2313 ALOGV("Opened DSP successfully");
2314 } else {
2315 pcm_device->sound_trigger_handle = 0;
2316 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2317 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2318
2319 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2320 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2321 pcm_close(pcm_device->pcm);
2322 pcm_device->pcm = NULL;
2323 ret = -EIO;
2324 goto error_open;
2325 }
2326 }
2327
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002328skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002329 /* force read and proc buffer reallocation in case of frame size or
2330 * channel count change */
2331 in->proc_buf_frames = 0;
2332 in->proc_buf_size = 0;
2333 in->read_buf_size = 0;
2334 in->read_buf_frames = 0;
2335
2336 /* if no supported sample rate is available, use the resampler */
2337 if (in->resampler) {
2338 in->resampler->reset(in->resampler);
2339 }
2340
2341 ALOGV("%s: exit", __func__);
2342 return ret;
2343
2344error_open:
2345 if (in->resampler) {
2346 release_resampler(in->resampler);
2347 in->resampler = NULL;
2348 }
2349 stop_input_stream(in);
2350
2351error_config:
2352 ALOGV("%s: exit: status(%d)", __func__, ret);
2353 adev->active_input = NULL;
2354 return ret;
2355}
2356
2357void lock_input_stream(struct stream_in *in)
2358{
2359 pthread_mutex_lock(&in->pre_lock);
2360 pthread_mutex_lock(&in->lock);
2361 pthread_mutex_unlock(&in->pre_lock);
2362}
2363
2364void lock_output_stream(struct stream_out *out)
2365{
2366 pthread_mutex_lock(&out->pre_lock);
2367 pthread_mutex_lock(&out->lock);
2368 pthread_mutex_unlock(&out->pre_lock);
2369}
2370
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002371static int uc_release_pcm_devices(struct audio_usecase *usecase)
2372{
2373 struct stream_out *out = (struct stream_out *)usecase->stream;
2374 struct pcm_device *pcm_device;
2375 struct listnode *node;
2376 struct listnode *next;
2377
2378 list_for_each_safe(node, next, &out->pcm_dev_list) {
2379 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2380 list_remove(node);
2381 free(pcm_device);
2382 }
2383 list_init(&usecase->mixer_list);
2384
2385 return 0;
2386}
2387
2388static int uc_select_pcm_devices(struct audio_usecase *usecase)
2389
2390{
2391 struct stream_out *out = (struct stream_out *)usecase->stream;
2392 struct pcm_device *pcm_device;
2393 struct pcm_device_profile *pcm_profile;
2394 struct mixer_card *mixer_card;
2395 audio_devices_t devices = usecase->devices;
2396
2397 list_init(&usecase->mixer_list);
2398 list_init(&out->pcm_dev_list);
2399
2400 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2401 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002402 if (pcm_device == NULL) {
2403 return -ENOMEM;
2404 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002405 pcm_device->pcm_profile = pcm_profile;
2406 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2407 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2408 if (mixer_card == NULL) {
2409 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2410 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2411 }
2412 devices &= ~pcm_profile->devices;
2413 }
2414
2415 return 0;
2416}
2417
2418static int out_close_pcm_devices(struct stream_out *out)
2419{
2420 struct pcm_device *pcm_device;
2421 struct listnode *node;
2422 struct audio_device *adev = out->dev;
2423
2424 list_for_each(node, &out->pcm_dev_list) {
2425 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2426 if (pcm_device->sound_trigger_handle > 0) {
2427 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2428 pcm_device->sound_trigger_handle = 0;
2429 }
2430 if (pcm_device->pcm) {
2431 pcm_close(pcm_device->pcm);
2432 pcm_device->pcm = NULL;
2433 }
2434 if (pcm_device->resampler) {
2435 release_resampler(pcm_device->resampler);
2436 pcm_device->resampler = NULL;
2437 }
2438 if (pcm_device->res_buffer) {
2439 free(pcm_device->res_buffer);
2440 pcm_device->res_buffer = NULL;
2441 }
2442 }
2443
2444 return 0;
2445}
2446
2447static int out_open_pcm_devices(struct stream_out *out)
2448{
2449 struct pcm_device *pcm_device;
2450 struct listnode *node;
2451 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002452 int pcm_device_card;
2453 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002454
2455 list_for_each(node, &out->pcm_dev_list) {
2456 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002457 pcm_device_card = pcm_device->pcm_profile->card;
2458 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002459
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002460 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2461 pcm_device_id = pcm_device_deep_buffer.id;
2462
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002463 if (out->dev->voice.in_call) {
2464 ALOGV("%s: in_call, not opening PCMs", __func__);
2465 return ret;
2466 }
2467
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002468 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2469 __func__, pcm_device_card, pcm_device_id);
2470
2471 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002472 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2473
2474 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2475 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2476 pcm_device->pcm = NULL;
2477 ret = -EIO;
2478 goto error_open;
2479 }
2480 /*
2481 * If the stream rate differs from the PCM rate, we need to
2482 * create a resampler.
2483 */
2484 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2485 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2486 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002487 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002488 out->sample_rate, pcm_device->pcm_profile->config.rate);
2489 ret = create_resampler(out->sample_rate,
2490 pcm_device->pcm_profile->config.rate,
2491 audio_channel_count_from_out_mask(out->channel_mask),
2492 RESAMPLER_QUALITY_DEFAULT,
2493 NULL,
2494 &pcm_device->resampler);
2495 pcm_device->res_byte_count = 0;
2496 pcm_device->res_buffer = NULL;
2497 }
2498 }
2499 return ret;
2500
2501error_open:
2502 out_close_pcm_devices(out);
2503 return ret;
2504}
2505
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002506int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002507{
2508 struct audio_device *adev = out->dev;
2509 struct audio_usecase *uc_info;
2510
2511 uc_info = get_usecase_from_id(adev, out->usecase);
2512 if (uc_info == NULL) {
2513 ALOGE("%s: Could not find the usecase (%d) in the list",
2514 __func__, out->usecase);
2515 return -EINVAL;
2516 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002517 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002518 uc_release_pcm_devices(uc_info);
2519 list_remove(&uc_info->adev_list_node);
2520 free(uc_info);
2521
2522 return 0;
2523}
2524
Andreas Schneider56204f62017-01-31 08:17:32 +01002525int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002526{
2527 struct audio_device *adev = out->dev;
2528 struct audio_usecase *uc_info;
2529
2530 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002531 if (uc_info == NULL) {
2532 return -ENOMEM;
2533 }
2534
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002535 uc_info->id = out->usecase;
2536 uc_info->type = PCM_PLAYBACK;
2537 uc_info->stream = (struct audio_stream *)out;
2538 uc_info->devices = out->devices;
2539 uc_info->in_snd_device = SND_DEVICE_NONE;
2540 uc_info->out_snd_device = SND_DEVICE_NONE;
2541 uc_select_pcm_devices(uc_info);
2542
2543 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2544 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002545
2546 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002547}
2548
2549static int stop_output_stream(struct stream_out *out)
2550{
2551 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002552 bool do_disable = true;
2553
2554 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2555 out->usecase, use_case_table[out->usecase]);
2556
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002557 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002558
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002559 if (do_disable)
2560 ret = disable_output_path_l(out);
2561
2562 ALOGV("%s: exit: status(%d)", __func__, ret);
2563 return ret;
2564}
2565
2566static int start_output_stream(struct stream_out *out)
2567{
2568 int ret = 0;
2569 struct audio_device *adev = out->dev;
2570
2571 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2572 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2573
Andreas Schneider56204f62017-01-31 08:17:32 +01002574 ret = enable_output_path_l(out);
2575 if (ret != 0) {
2576 goto error_config;
2577 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002578
2579 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2580 out->compr = NULL;
2581 ret = out_open_pcm_devices(out);
2582 if (ret != 0)
2583 goto error_open;
2584#ifdef PREPROCESSING_ENABLED
2585 out->echo_reference = NULL;
2586 out->echo_reference_generation = adev->echo_reference_generation;
2587 if (adev->echo_reference != NULL)
2588 out->echo_reference = adev->echo_reference;
2589#endif
2590 } else {
2591 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2592 COMPRESS_IN, &out->compr_config);
2593 if (out->compr && !is_compress_ready(out->compr)) {
2594 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2595 compress_close(out->compr);
2596 out->compr = NULL;
2597 ret = -EIO;
2598 goto error_open;
2599 }
2600 if (out->offload_callback)
2601 compress_nonblock(out->compr, out->non_blocking);
2602
2603 if (adev->offload_fx_start_output != NULL)
2604 adev->offload_fx_start_output(out->handle);
2605 }
2606 ALOGV("%s: exit", __func__);
2607 return 0;
2608error_open:
2609 stop_output_stream(out);
2610error_config:
2611 return ret;
2612}
2613
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002614int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002615{
2616 struct audio_usecase *uc_info;
2617
2618 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002619 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002620
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002621 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002622
2623 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2624 if (uc_info == NULL) {
2625 ALOGE("%s: Could not find the usecase (%d) in the list",
2626 __func__, USECASE_VOICE_CALL);
2627 return -EINVAL;
2628 }
2629
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002630 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2631 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002632
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002633 list_remove(&uc_info->adev_list_node);
2634 free(uc_info);
2635
2636 ALOGV("%s: exit", __func__);
2637 return 0;
2638}
2639
2640/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002641int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002642{
2643 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002644 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002645
2646 ALOGV("%s: enter", __func__);
2647
2648 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002649 if (uc_info == NULL) {
2650 ret = -ENOMEM;
2651 goto exit;
2652 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002653 /*
2654 * We set this early so that functions called after this is being set
2655 * can use it. It is e.g. needed in select_devices() to inform the RILD
2656 * which output device we use.
2657 */
2658 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002659
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002660 uc_info->id = USECASE_VOICE_CALL;
2661 uc_info->type = VOICE_CALL;
2662 uc_info->stream = (struct audio_stream *)adev->primary_output;
2663 uc_info->devices = adev->primary_output->devices;
2664 uc_info->in_snd_device = SND_DEVICE_NONE;
2665 uc_info->out_snd_device = SND_DEVICE_NONE;
2666
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002667 list_init(&uc_info->mixer_list);
2668 list_add_tail(&uc_info->mixer_list,
2669 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002670
2671 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2672
2673 select_devices(adev, USECASE_VOICE_CALL);
2674
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002675 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002676
2677 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002678 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002679
Andreas Schneider56204f62017-01-31 08:17:32 +01002680exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002681 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002682 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002683}
2684
2685static int check_input_parameters(uint32_t sample_rate,
2686 audio_format_t format,
2687 int channel_count)
2688{
2689 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2690
2691 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2692
2693 switch (sample_rate) {
2694 case 8000:
2695 case 11025:
2696 case 12000:
2697 case 16000:
2698 case 22050:
2699 case 24000:
2700 case 32000:
2701 case 44100:
2702 case 48000:
2703 break;
2704 default:
2705 return -EINVAL;
2706 }
2707
2708 return 0;
2709}
2710
2711static size_t get_input_buffer_size(uint32_t sample_rate,
2712 audio_format_t format,
2713 int channel_count,
2714 usecase_type_t usecase_type,
2715 audio_devices_t devices)
2716{
2717 size_t size = 0;
2718 struct pcm_device_profile *pcm_profile;
2719
2720 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2721 return 0;
2722
2723 pcm_profile = get_pcm_device(usecase_type, devices);
2724 if (pcm_profile == NULL)
2725 return 0;
2726
2727 /*
2728 * take resampling into account and return the closest majoring
2729 * multiple of 16 frames, as audioflinger expects audio buffers to
2730 * be a multiple of 16 frames
2731 */
2732 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2733 size = ((size + 15) / 16) * 16;
2734
2735 return (size * channel_count * audio_bytes_per_sample(format));
2736
2737}
2738
2739static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2740{
2741 struct stream_out *out = (struct stream_out *)stream;
2742
2743 return out->sample_rate;
2744}
2745
2746static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2747{
2748 (void)stream;
2749 (void)rate;
2750 return -ENOSYS;
2751}
2752
2753static size_t out_get_buffer_size(const struct audio_stream *stream)
2754{
2755 struct stream_out *out = (struct stream_out *)stream;
2756
2757 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2758 return out->compr_config.fragment_size;
2759 }
2760
2761 return out->config.period_size *
2762 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2763}
2764
2765static uint32_t out_get_channels(const struct audio_stream *stream)
2766{
2767 struct stream_out *out = (struct stream_out *)stream;
2768
2769 return out->channel_mask;
2770}
2771
2772static audio_format_t out_get_format(const struct audio_stream *stream)
2773{
2774 struct stream_out *out = (struct stream_out *)stream;
2775
2776 return out->format;
2777}
2778
2779static int out_set_format(struct audio_stream *stream, audio_format_t format)
2780{
2781 (void)stream;
2782 (void)format;
2783 return -ENOSYS;
2784}
2785
2786static int do_out_standby_l(struct stream_out *out)
2787{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002788 int status = 0;
2789
2790 out->standby = true;
2791 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2792 out_close_pcm_devices(out);
2793#ifdef PREPROCESSING_ENABLED
2794 /* stop writing to echo reference */
2795 if (out->echo_reference != NULL) {
2796 out->echo_reference->write(out->echo_reference, NULL);
2797 if (out->echo_reference_generation != adev->echo_reference_generation) {
2798 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2799 release_echo_reference(out->echo_reference);
2800 out->echo_reference_generation = adev->echo_reference_generation;
2801 }
2802 out->echo_reference = NULL;
2803 }
2804#endif
2805 } else {
2806 stop_compressed_output_l(out);
2807 out->gapless_mdata.encoder_delay = 0;
2808 out->gapless_mdata.encoder_padding = 0;
2809 if (out->compr != NULL) {
2810 compress_close(out->compr);
2811 out->compr = NULL;
2812 }
2813 }
2814 status = stop_output_stream(out);
2815
2816 return status;
2817}
2818
2819static int out_standby(struct audio_stream *stream)
2820{
2821 struct stream_out *out = (struct stream_out *)stream;
2822 struct audio_device *adev = out->dev;
2823
2824 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2825 out->usecase, use_case_table[out->usecase]);
2826 lock_output_stream(out);
2827 if (!out->standby) {
2828 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002829 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002830 do_out_standby_l(out);
2831 pthread_mutex_unlock(&adev->lock);
2832 }
2833 pthread_mutex_unlock(&out->lock);
2834 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002835
2836 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2837
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002838 return 0;
2839}
2840
2841static int out_dump(const struct audio_stream *stream, int fd)
2842{
2843 (void)stream;
2844 (void)fd;
2845
2846 return 0;
2847}
2848
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002849static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2850{
2851 struct stream_out *out = (struct stream_out *)stream;
2852 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002853 struct listnode *node;
2854 struct str_parms *parms;
2855 char value[32];
2856 int ret, val = 0;
2857 struct audio_usecase *uc_info;
2858 bool do_standby = false;
2859 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002860#ifdef PREPROCESSING_ENABLED
2861 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2862#endif
2863
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002864 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2865 "adev->mode(%#x)",
2866 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2867 out->devices, adev->mode);
2868
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002869 parms = str_parms_create_str(kvpairs);
2870 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2871 if (ret >= 0) {
2872 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002873
2874 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2875 __func__, out->usecase, use_case_table[out->usecase], val,
2876 adev->mode);
2877
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002878 pthread_mutex_lock(&adev->lock_inputs);
2879 lock_output_stream(out);
2880 pthread_mutex_lock(&adev->lock);
2881#ifdef PREPROCESSING_ENABLED
2882 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2883 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2884 /* reset active input:
2885 * - to attach the echo reference
2886 * - because a change in output device may change mic settings */
2887 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2888 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2889 in = adev->active_input;
2890 }
2891 }
2892#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002893 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002894 bool bt_sco_active = false;
2895
2896 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2897 bt_sco_active = true;
2898 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002899 out->devices = val;
2900
2901 if (!out->standby) {
2902 uc_info = get_usecase_from_id(adev, out->usecase);
2903 if (uc_info == NULL) {
2904 ALOGE("%s: Could not find the usecase (%d) in the list",
2905 __func__, out->usecase);
2906 } else {
2907 list_for_each(node, &out->pcm_dev_list) {
2908 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2909 if ((pcm_device->pcm_profile->devices & val) == 0)
2910 do_standby = true;
2911 val &= ~pcm_device->pcm_profile->devices;
2912 }
2913 if (val != 0)
2914 do_standby = true;
2915 }
2916 if (do_standby)
2917 do_out_standby_l(out);
2918 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002919 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2920 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002921 select_devices(adev, out->usecase);
2922 }
2923 }
2924
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002925 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002926 (out == adev->primary_output)) {
2927 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002928 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2929 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002930 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002931 /* Turn on bluetooth if needed */
2932 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002933 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002934 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002935 } else {
2936 /*
2937 * When we select different devices we need to restart the
2938 * voice call. The modem closes the stream on its end and
2939 * we do not get any output.
2940 */
2941 stop_voice_call(adev);
2942 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002943 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002944 }
2945 }
2946
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002947 pthread_mutex_unlock(&adev->lock);
2948 pthread_mutex_unlock(&out->lock);
2949#ifdef PREPROCESSING_ENABLED
2950 if (in) {
2951 /* The lock on adev->lock_inputs prevents input stream from being closed */
2952 lock_input_stream(in);
2953 pthread_mutex_lock(&adev->lock);
2954 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2955 do_in_standby_l(in);
2956 pthread_mutex_unlock(&adev->lock);
2957 pthread_mutex_unlock(&in->lock);
2958 }
2959#endif
2960 pthread_mutex_unlock(&adev->lock_inputs);
2961 }
2962
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002963 amplifier_set_parameters(parms);
2964
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002965 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2966 parse_compress_metadata(out, parms);
2967 }
2968
2969 str_parms_destroy(parms);
2970
2971 if (ret > 0)
2972 ret = 0;
2973 ALOGV("%s: exit: code(%d)", __func__, ret);
2974 return ret;
2975}
2976
2977static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2978{
2979 struct stream_out *out = (struct stream_out *)stream;
2980 struct str_parms *query = str_parms_create_str(keys);
2981 char *str;
2982 char value[256];
2983 struct str_parms *reply = str_parms_create();
2984 size_t i, j;
2985 int ret;
2986 bool first = true;
2987 ALOGV("%s: enter: keys - %s", __func__, keys);
2988 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2989 if (ret >= 0) {
2990 value[0] = '\0';
2991 i = 0;
2992 while (out->supported_channel_masks[i] != 0) {
2993 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2994 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2995 if (!first) {
2996 strcat(value, "|");
2997 }
2998 strcat(value, out_channels_name_to_enum_table[j].name);
2999 first = false;
3000 break;
3001 }
3002 }
3003 i++;
3004 }
3005 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
3006 str = str_parms_to_str(reply);
3007 } else {
3008 str = strdup(keys);
3009 }
3010 str_parms_destroy(query);
3011 str_parms_destroy(reply);
3012 ALOGV("%s: exit: returns - %s", __func__, str);
3013 return str;
3014}
3015
3016static uint32_t out_get_latency(const struct audio_stream_out *stream)
3017{
3018 struct stream_out *out = (struct stream_out *)stream;
3019
3020 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3021 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
3022
3023 return (out->config.period_count * out->config.period_size * 1000) /
3024 (out->config.rate);
3025}
3026
3027static int out_set_volume(struct audio_stream_out *stream, float left,
3028 float right)
3029{
3030 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003031
3032 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
3033 /* only take left channel into account: the API is for stereo anyway */
3034 out->muted = (left == 0.0f);
3035 return 0;
3036 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003037 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003038 }
3039
3040 return -ENOSYS;
3041}
3042
Andreas Schneider3b643832017-01-31 11:48:22 +01003043#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003044static int fast_set_affinity(pid_t tid) {
3045 cpu_set_t cpu_set;
3046 int cpu_num;
3047 const char *irq_procfs = "/proc/asound/irq_affinity";
3048 FILE *fp;
3049
3050 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3051 ALOGW("Procfs node %s not found", irq_procfs);
3052 return -1;
3053 }
3054
3055 if (fscanf(fp, "%d", &cpu_num) != 1) {
3056 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3057 fclose(fp);
3058 return -1;
3059 }
3060 fclose(fp);
3061
3062 CPU_ZERO(&cpu_set);
3063 CPU_SET(cpu_num, &cpu_set);
3064 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3065}
Andreas Schneider3b643832017-01-31 11:48:22 +01003066#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003067
3068static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3069 size_t bytes)
3070{
3071 struct stream_out *out = (struct stream_out *)stream;
3072 struct audio_device *adev = out->dev;
3073 ssize_t ret = 0;
3074 struct pcm_device *pcm_device;
3075 struct listnode *node;
3076 size_t frame_size = audio_stream_out_frame_size(stream);
3077 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003078#ifdef PREPROCESSING_ENABLED
3079 size_t in_frames = bytes / frame_size;
3080 size_t out_frames = in_frames;
3081 struct stream_in *in = NULL;
3082#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003083
3084 lock_output_stream(out);
3085
Andreas Schneider3b643832017-01-31 11:48:22 +01003086#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003087 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003088 pid_t tid = gettid();
3089 int err;
3090
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003091 err = fast_set_affinity(tid);
3092 if (err < 0) {
3093 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3094 }
3095 out->is_fastmixer_affinity_set = true;
3096 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003097#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003098
3099 if (out->standby) {
3100#ifdef PREPROCESSING_ENABLED
3101 pthread_mutex_unlock(&out->lock);
3102 /* Prevent input stream from being closed */
3103 pthread_mutex_lock(&adev->lock_inputs);
3104 lock_output_stream(out);
3105 if (!out->standby) {
3106 pthread_mutex_unlock(&adev->lock_inputs);
3107 goto false_alarm;
3108 }
3109#endif
3110 pthread_mutex_lock(&adev->lock);
3111 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003112 if (ret == 0) {
3113 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3114 }
3115
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003116 /* ToDo: If use case is compress offload should return 0 */
3117 if (ret != 0) {
3118 pthread_mutex_unlock(&adev->lock);
3119#ifdef PREPROCESSING_ENABLED
3120 pthread_mutex_unlock(&adev->lock_inputs);
3121#endif
3122 goto exit;
3123 }
3124 out->standby = false;
3125
3126#ifdef PREPROCESSING_ENABLED
3127 /* A change in output device may change the microphone selection */
3128 if (adev->active_input &&
3129 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3130 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3131 in = adev->active_input;
3132 ALOGV("%s: enter:) force_input_standby true", __func__);
3133 }
3134#endif
3135 pthread_mutex_unlock(&adev->lock);
3136#ifdef PREPROCESSING_ENABLED
3137 if (!in) {
3138 /* Leave mutex locked iff in != NULL */
3139 pthread_mutex_unlock(&adev->lock_inputs);
3140 }
3141#endif
3142 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003143#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003144false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003145#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003146
3147 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003148 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003149 return ret;
3150 } else {
3151#ifdef PREPROCESSING_ENABLED
3152 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3153 != out->echo_reference_generation) {
3154 pthread_mutex_lock(&adev->lock);
3155 if (out->echo_reference != NULL) {
3156 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3157 release_echo_reference(out->echo_reference);
3158 }
3159 // note that adev->echo_reference_generation here can be different from the one
3160 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3161 // with what has been set by get_echo_reference() or put_echo_reference()
3162 out->echo_reference_generation = adev->echo_reference_generation;
3163 out->echo_reference = adev->echo_reference;
3164 ALOGV("%s: update echo reference generation %d", __func__,
3165 out->echo_reference_generation);
3166 pthread_mutex_unlock(&adev->lock);
3167 }
3168#endif
3169
3170 if (out->muted)
3171 memset((void *)buffer, 0, bytes);
3172 list_for_each(node, &out->pcm_dev_list) {
3173 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3174 if (pcm_device->resampler) {
3175 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3176 > pcm_device->res_byte_count) {
3177 pcm_device->res_byte_count =
3178 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3179 pcm_device->res_buffer =
3180 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3181 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3182 pcm_device->res_byte_count);
3183 }
3184 frames_rq = bytes / frame_size;
3185 frames_wr = pcm_device->res_byte_count / frame_size;
3186 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3187 __func__, frames_rq, frame_size);
3188 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3189 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3190 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3191 }
3192 if (pcm_device->pcm) {
3193#ifdef PREPROCESSING_ENABLED
3194 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3195 struct echo_reference_buffer b;
3196 b.raw = (void *)buffer;
3197 b.frame_count = in_frames;
3198
3199 get_playback_delay(out, out_frames, &b);
3200 out->echo_reference->write(out->echo_reference, &b);
3201 }
3202#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003203 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3204 if (pcm_device->resampler && pcm_device->res_buffer)
3205 pcm_device->status =
3206 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3207 frames_wr * frame_size);
3208 else
3209 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3210 if (pcm_device->status != 0)
3211 ret = pcm_device->status;
3212 }
3213 }
3214 if (ret == 0)
3215 out->written += bytes / (out->config.channels * sizeof(short));
3216 }
3217
3218exit:
3219 pthread_mutex_unlock(&out->lock);
3220
3221 if (ret != 0) {
3222 list_for_each(node, &out->pcm_dev_list) {
3223 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3224 if (pcm_device->pcm && pcm_device->status != 0)
3225 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3226 }
3227 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003228 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3229 clock_gettime(CLOCK_MONOTONIC, &t);
3230 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3231 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3232 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3233 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3234 if (sleep_time > 0) {
3235 usleep(sleep_time);
3236 } else {
3237 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3238 sleep_time = 0;
3239 }
3240 out->last_write_time_us = now + sleep_time;
3241 // last_write_time_us is an approximation of when the (simulated) alsa
3242 // buffer is believed completely full. The usleep above waits for more space
3243 // in the buffer, but by the end of the sleep the buffer is considered
3244 // topped-off.
3245 //
3246 // On the subsequent out_write(), we measure the elapsed time spent in
3247 // the mixer. This is subtracted from the sleep estimate based on frames,
3248 // thereby accounting for drain in the alsa buffer during mixing.
3249 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003250 }
3251
3252#ifdef PREPROCESSING_ENABLED
3253 if (in) {
3254 /* The lock on adev->lock_inputs prevents input stream from being closed */
3255 lock_input_stream(in);
3256 pthread_mutex_lock(&adev->lock);
3257 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3258 do_in_standby_l(in);
3259 pthread_mutex_unlock(&adev->lock);
3260 pthread_mutex_unlock(&in->lock);
3261 /* This mutex was left locked iff in != NULL */
3262 pthread_mutex_unlock(&adev->lock_inputs);
3263 }
3264#endif
3265
3266 return bytes;
3267}
3268
3269static int out_get_render_position(const struct audio_stream_out *stream,
3270 uint32_t *dsp_frames)
3271{
3272 struct stream_out *out = (struct stream_out *)stream;
3273 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003274 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3275 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003276 } else
3277 return -EINVAL;
3278}
3279
3280static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3281{
3282 (void)stream;
3283 (void)effect;
3284 return 0;
3285}
3286
3287static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3288{
3289 (void)stream;
3290 (void)effect;
3291 return 0;
3292}
3293
3294static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3295 int64_t *timestamp)
3296{
3297 (void)stream;
3298 (void)timestamp;
3299 return -EINVAL;
3300}
3301
3302static int out_get_presentation_position(const struct audio_stream_out *stream,
3303 uint64_t *frames, struct timespec *timestamp)
3304{
3305 struct stream_out *out = (struct stream_out *)stream;
3306 int ret = -1;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003307
3308 lock_output_stream(out);
3309
3310 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003311 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003312 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003313 if (out->dev->voice.in_call) {
3314 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3315 ret = 0;
3316 goto done;
3317 }
3318
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003319 /* FIXME: which device to read from? */
3320 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003321 struct pcm_device *pcm_device;
3322 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003323 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003324
Andreas Schneiderd6359182017-02-08 16:58:22 +01003325 list_for_each(node, &out->pcm_dev_list) {
3326 pcm_device = node_to_item(node,
3327 struct pcm_device,
3328 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003329
Andreas Schneiderd6359182017-02-08 16:58:22 +01003330 if (pcm_device->pcm != NULL) {
3331 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3332 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3333 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3334 /* This adjustment accounts for buffering after app processor.
3335 It is based on estimated DSP latency per use case, rather than exact. */
3336 signed_frames -=
3337 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3338
3339 /* It would be unusual for this value to be negative, but check just in case ... */
3340 if (signed_frames >= 0) {
3341 *frames = signed_frames;
3342 ret = 0;
3343 goto done;
3344 }
3345 ret = -1;
3346 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003347 }
3348 }
3349 }
3350 }
3351
Andreas Schneiderd6359182017-02-08 16:58:22 +01003352done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003353 pthread_mutex_unlock(&out->lock);
3354
3355 return ret;
3356}
3357
3358static int out_set_callback(struct audio_stream_out *stream,
3359 stream_callback_t callback, void *cookie)
3360{
3361 struct stream_out *out = (struct stream_out *)stream;
3362
3363 ALOGV("%s", __func__);
3364 lock_output_stream(out);
3365 out->offload_callback = callback;
3366 out->offload_cookie = cookie;
3367 pthread_mutex_unlock(&out->lock);
3368 return 0;
3369}
3370
3371static int out_pause(struct audio_stream_out* stream)
3372{
3373 struct stream_out *out = (struct stream_out *)stream;
3374 int status = -ENOSYS;
3375 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003376 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3377 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003378 return status;
3379}
3380
3381static int out_resume(struct audio_stream_out* stream)
3382{
3383 struct stream_out *out = (struct stream_out *)stream;
3384 int status = -ENOSYS;
3385 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003386 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3387 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003388 return status;
3389}
3390
3391static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3392{
3393 struct stream_out *out = (struct stream_out *)stream;
3394 int status = -ENOSYS;
3395 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003396 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3397 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003398 return status;
3399}
3400
3401static int out_flush(struct audio_stream_out* stream)
3402{
3403 struct stream_out *out = (struct stream_out *)stream;
3404 ALOGV("%s", __func__);
3405 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003406 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003407 }
3408 return -ENOSYS;
3409}
3410
3411/** audio_stream_in implementation **/
3412static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3413{
3414 struct stream_in *in = (struct stream_in *)stream;
3415
3416 return in->requested_rate;
3417}
3418
3419static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3420{
3421 (void)stream;
3422 (void)rate;
3423 return -ENOSYS;
3424}
3425
3426static uint32_t in_get_channels(const struct audio_stream *stream)
3427{
3428 struct stream_in *in = (struct stream_in *)stream;
3429
3430 return in->main_channels;
3431}
3432
3433static audio_format_t in_get_format(const struct audio_stream *stream)
3434{
3435 (void)stream;
3436 return AUDIO_FORMAT_PCM_16_BIT;
3437}
3438
3439static int in_set_format(struct audio_stream *stream, audio_format_t format)
3440{
3441 (void)stream;
3442 (void)format;
3443
3444 return -ENOSYS;
3445}
3446
3447static size_t in_get_buffer_size(const struct audio_stream *stream)
3448{
3449 struct stream_in *in = (struct stream_in *)stream;
3450
3451 return get_input_buffer_size(in->requested_rate,
3452 in_get_format(stream),
3453 audio_channel_count_from_in_mask(in->main_channels),
3454 in->usecase_type,
3455 in->devices);
3456}
3457
3458static int in_close_pcm_devices(struct stream_in *in)
3459{
3460 struct pcm_device *pcm_device;
3461 struct listnode *node;
3462 struct audio_device *adev = in->dev;
3463
3464 list_for_each(node, &in->pcm_dev_list) {
3465 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3466 if (pcm_device) {
3467 if (pcm_device->pcm)
3468 pcm_close(pcm_device->pcm);
3469 pcm_device->pcm = NULL;
3470 if (pcm_device->sound_trigger_handle > 0)
3471 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3472 pcm_device->sound_trigger_handle = 0;
3473 }
3474 }
3475 return 0;
3476}
3477
3478
3479/* must be called with stream and hw device mutex locked */
3480static int do_in_standby_l(struct stream_in *in)
3481{
3482 int status = 0;
3483
3484#ifdef PREPROCESSING_ENABLED
3485 struct audio_device *adev = in->dev;
3486#endif
3487 if (!in->standby) {
3488
3489 in_close_pcm_devices(in);
3490
3491#ifdef PREPROCESSING_ENABLED
3492 if (in->echo_reference != NULL) {
3493 /* stop reading from echo reference */
3494 in->echo_reference->read(in->echo_reference, NULL);
3495 put_echo_reference(adev, in->echo_reference);
3496 in->echo_reference = NULL;
3497 }
3498#ifdef HW_AEC_LOOPBACK
3499 if (in->hw_echo_reference)
3500 {
3501 if (in->hw_ref_buf) {
3502 free(in->hw_ref_buf);
3503 in->hw_ref_buf = NULL;
3504 }
3505 }
3506#endif // HW_AEC_LOOPBACK
3507#endif // PREPROCESSING_ENABLED
3508
3509 status = stop_input_stream(in);
3510
3511 if (in->read_buf) {
3512 free(in->read_buf);
3513 in->read_buf = NULL;
3514 }
3515
3516 in->standby = 1;
3517 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003518
3519 in->last_read_time_us = 0;
3520
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003521 return 0;
3522}
3523
3524// called with adev->lock_inputs locked
3525static int in_standby_l(struct stream_in *in)
3526{
3527 struct audio_device *adev = in->dev;
3528 int status = 0;
3529 lock_input_stream(in);
3530 if (!in->standby) {
3531 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003532 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003533 status = do_in_standby_l(in);
3534 pthread_mutex_unlock(&adev->lock);
3535 }
3536 pthread_mutex_unlock(&in->lock);
3537 return status;
3538}
3539
3540static int in_standby(struct audio_stream *stream)
3541{
3542 struct stream_in *in = (struct stream_in *)stream;
3543 struct audio_device *adev = in->dev;
3544 int status;
3545 ALOGV("%s: enter", __func__);
3546 pthread_mutex_lock(&adev->lock_inputs);
3547 status = in_standby_l(in);
3548 pthread_mutex_unlock(&adev->lock_inputs);
3549 ALOGV("%s: exit: status(%d)", __func__, status);
3550 return status;
3551}
3552
3553static int in_dump(const struct audio_stream *stream, int fd)
3554{
3555 (void)stream;
3556 (void)fd;
3557
3558 return 0;
3559}
3560
3561static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3562{
3563 struct stream_in *in = (struct stream_in *)stream;
3564 struct audio_device *adev = in->dev;
3565 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003566 char value[32];
3567 int ret, val = 0;
3568 struct audio_usecase *uc_info;
3569 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003570 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003571
3572 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3573 parms = str_parms_create_str(kvpairs);
3574
3575 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3576
3577 pthread_mutex_lock(&adev->lock_inputs);
3578 lock_input_stream(in);
3579 pthread_mutex_lock(&adev->lock);
3580 if (ret >= 0) {
3581 val = atoi(value);
3582 /* no audio source uses val == 0 */
3583 if (((int)in->source != val) && (val != 0)) {
3584 in->source = val;
3585 }
3586 }
3587
3588 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3589 if (ret >= 0) {
3590 val = atoi(value);
3591 if (((int)in->devices != val) && (val != 0)) {
3592 in->devices = val;
3593 /* If recording is in progress, change the tx device to new device */
3594 if (!in->standby) {
3595 uc_info = get_usecase_from_id(adev, in->usecase);
3596 if (uc_info == NULL) {
3597 ALOGE("%s: Could not find the usecase (%d) in the list",
3598 __func__, in->usecase);
3599 } else {
3600 if (list_empty(&in->pcm_dev_list))
3601 ALOGE("%s: pcm device list empty", __func__);
3602 else {
3603 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3604 struct pcm_device, stream_list_node);
3605 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3606 do_standby = true;
3607 }
3608 }
3609 }
3610 if (do_standby) {
3611 ret = do_in_standby_l(in);
3612 } else
3613 ret = select_devices(adev, in->usecase);
3614 }
3615 }
3616 }
3617 pthread_mutex_unlock(&adev->lock);
3618 pthread_mutex_unlock(&in->lock);
3619 pthread_mutex_unlock(&adev->lock_inputs);
3620 str_parms_destroy(parms);
3621
3622 if (ret > 0)
3623 ret = 0;
3624
3625 ALOGV("%s: exit: status(%d)", __func__, ret);
3626 return ret;
3627}
3628
3629static char* in_get_parameters(const struct audio_stream *stream,
3630 const char *keys)
3631{
3632 (void)stream;
3633 (void)keys;
3634
3635 return strdup("");
3636}
3637
3638static int in_set_gain(struct audio_stream_in *stream, float gain)
3639{
3640 (void)stream;
3641 (void)gain;
3642
3643 return 0;
3644}
3645
3646static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3647 size_t bytes)
3648{
3649 struct pcm_device *pcm_device;
3650 struct audio_device *adev = in->dev;
3651
3652 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3653 struct pcm_device, stream_list_node);
3654
3655 if (pcm_device->sound_trigger_handle > 0)
3656 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3657 else
3658 return 0;
3659}
3660
3661static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3662 size_t bytes)
3663{
3664 struct stream_in *in = (struct stream_in *)stream;
3665 struct audio_device *adev = in->dev;
3666 ssize_t frames = -1;
3667 int ret = -1;
3668 int read_and_process_successful = false;
3669
3670 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003671
3672 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3673 lock_input_stream(in);
3674
Andreas Schneider3b643832017-01-31 11:48:22 +01003675#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003676 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003677 pid_t tid = gettid();
3678 int err;
3679
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003680 err = fast_set_affinity(tid);
3681 if (err < 0) {
3682 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3683 }
3684 in->is_fastcapture_affinity_set = true;
3685 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003686#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003687
3688 if (in->standby) {
3689 pthread_mutex_unlock(&in->lock);
3690 pthread_mutex_lock(&adev->lock_inputs);
3691 lock_input_stream(in);
3692 if (!in->standby) {
3693 pthread_mutex_unlock(&adev->lock_inputs);
3694 goto false_alarm;
3695 }
3696 pthread_mutex_lock(&adev->lock);
3697 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003698 if (ret == 0) {
3699 amplifier_input_stream_start(stream);
3700 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003701 pthread_mutex_unlock(&adev->lock);
3702 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003703
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003704 if (ret != 0) {
3705 goto exit;
3706 }
3707 in->standby = 0;
3708 }
3709false_alarm:
3710
3711 if (!list_empty(&in->pcm_dev_list)) {
3712 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3713 bytes = read_bytes_from_dsp(in, buffer, bytes);
3714 if (bytes > 0)
3715 read_and_process_successful = true;
3716 } else {
3717 /*
3718 * Read PCM and:
3719 * - resample if needed
3720 * - process if pre-processors are attached
3721 * - discard unwanted channels
3722 */
3723 frames = read_and_process_frames(in, buffer, frames_rq);
3724 if (frames >= 0)
3725 read_and_process_successful = true;
3726 }
3727 }
3728
3729 /*
3730 * Instead of writing zeroes here, we could trust the hardware
3731 * to always provide zeroes when muted.
3732 */
3733 if (read_and_process_successful == true && adev->mic_mute)
3734 memset(buffer, 0, bytes);
3735
3736exit:
3737 pthread_mutex_unlock(&in->lock);
3738
3739 if (read_and_process_successful == false) {
3740 in_standby(&in->stream.common);
3741 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003742 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3743 clock_gettime(CLOCK_MONOTONIC, &t);
3744 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3745
3746 // we do a full sleep when exiting standby.
3747 const bool standby = in->last_read_time_us == 0;
3748 const int64_t elapsed_time_since_last_read = standby ?
3749 0 : now - in->last_read_time_us;
3750 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3751 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3752 if (sleep_time > 0) {
3753 usleep(sleep_time);
3754 } else {
3755 sleep_time = 0;
3756 }
3757 in->last_read_time_us = now + sleep_time;
3758 // last_read_time_us is an approximation of when the (simulated) alsa
3759 // buffer is drained by the read, and is empty.
3760 //
3761 // On the subsequent in_read(), we measure the elapsed time spent in
3762 // the recording thread. This is subtracted from the sleep estimate based on frames,
3763 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003764 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003765 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003766
3767 if (bytes > 0) {
3768 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3769 }
3770
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003771 return bytes;
3772}
3773
3774static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3775{
3776 (void)stream;
3777
3778 return 0;
3779}
3780
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003781static int in_get_capture_position(const struct audio_stream_in *stream,
3782 int64_t *frames, int64_t *time)
3783{
3784 if (stream == NULL || frames == NULL || time == NULL) {
3785 return -EINVAL;
3786 }
3787
3788 struct stream_in *in = (struct stream_in *)stream;
3789 struct pcm_device *pcm_device;
3790 int ret = -ENOSYS;
3791
3792 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3793 struct pcm_device, stream_list_node);
3794
3795 pthread_mutex_lock(&in->lock);
3796 if (pcm_device->pcm) {
3797 struct timespec timestamp;
3798 unsigned int avail;
3799 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3800 *frames = in->frames_read + avail;
3801 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3802 ret = 0;
3803 }
3804 }
3805
3806 pthread_mutex_unlock(&in->lock);
3807 return ret;
3808}
3809
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003810static int add_remove_audio_effect(const struct audio_stream *stream,
3811 effect_handle_t effect,
3812 bool enable)
3813{
3814 struct stream_in *in = (struct stream_in *)stream;
3815 struct audio_device *adev = in->dev;
3816 int status = 0;
3817 effect_descriptor_t desc;
3818#ifdef PREPROCESSING_ENABLED
3819 int i;
3820#endif
3821 status = (*effect)->get_descriptor(effect, &desc);
3822 if (status != 0)
3823 return status;
3824
3825 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3826
3827 pthread_mutex_lock(&adev->lock_inputs);
3828 lock_input_stream(in);
3829 pthread_mutex_lock(&in->dev->lock);
3830#ifndef PREPROCESSING_ENABLED
3831 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3832 in->enable_aec != enable &&
3833 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3834 in->enable_aec = enable;
3835 if (!in->standby)
3836 select_devices(in->dev, in->usecase);
3837 }
3838#else
3839 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3840 status = -ENOSYS;
3841 goto exit;
3842 }
3843 if ( enable == true ) {
3844 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3845 /* add the supported channel of the effect in the channel_configs */
3846 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3847 in->num_preprocessors ++;
3848 /* check compatibility between main channel supported and possible auxiliary channels */
3849 in_update_aux_channels(in, effect);//wesley crash
3850 in->aux_channels_changed = true;
3851 } else {
3852 /* if ( enable == false ) */
3853 if (in->num_preprocessors <= 0) {
3854 status = -ENOSYS;
3855 goto exit;
3856 }
3857 status = -EINVAL;
3858 for (i=0; i < in->num_preprocessors; i++) {
3859 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3860 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3861 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3862 in->preprocessors[i - 1].num_channel_configs =
3863 in->preprocessors[i].num_channel_configs;
3864 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3865 continue;
3866 }
3867 if ( in->preprocessors[i].effect_itfe == effect ) {
3868 ALOGV("add_remove_audio_effect found fx at index %d", i);
3869 free(in->preprocessors[i].channel_configs);
3870 status = 0;
3871 }
3872 }
3873 if (status != 0)
3874 goto exit;
3875 in->num_preprocessors--;
3876 /* if we remove one effect, at least the last proproc should be reset */
3877 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3878 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3879 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3880 in->aux_channels_changed = false;
3881 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3882 }
3883 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3884
3885 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3886 in->enable_aec = enable;
3887 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3888 if (!in->standby) {
3889 select_devices(in->dev, in->usecase);
3890 do_in_standby_l(in);
3891 }
3892 if (in->enable_aec == true) {
3893 in_configure_reverse(in);
3894 }
3895 }
3896exit:
3897#endif
3898 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3899 pthread_mutex_unlock(&in->dev->lock);
3900 pthread_mutex_unlock(&in->lock);
3901 pthread_mutex_unlock(&adev->lock_inputs);
3902 return status;
3903}
3904
3905static int in_add_audio_effect(const struct audio_stream *stream,
3906 effect_handle_t effect)
3907{
3908 ALOGV("%s: effect %p", __func__, effect);
3909 return add_remove_audio_effect(stream, effect, true);
3910}
3911
3912static int in_remove_audio_effect(const struct audio_stream *stream,
3913 effect_handle_t effect)
3914{
3915 ALOGV("%s: effect %p", __func__, effect);
3916 return add_remove_audio_effect(stream, effect, false);
3917}
3918
3919static int adev_open_output_stream(struct audio_hw_device *dev,
3920 audio_io_handle_t handle,
3921 audio_devices_t devices,
3922 audio_output_flags_t flags,
3923 struct audio_config *config,
3924 struct audio_stream_out **stream_out,
3925 const char *address __unused)
3926{
3927 struct audio_device *adev = (struct audio_device *)dev;
3928 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003929 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003930 struct pcm_device_profile *pcm_profile;
3931
3932 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3933 __func__, config->sample_rate, config->channel_mask, devices, flags);
3934 *stream_out = NULL;
3935 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003936 if (out == NULL) {
3937 ret = -ENOMEM;
3938 goto error_config;
3939 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003940
3941 if (devices == AUDIO_DEVICE_NONE)
3942 devices = AUDIO_DEVICE_OUT_SPEAKER;
3943
3944 out->flags = flags;
3945 out->devices = devices;
3946 out->dev = adev;
3947 out->format = config->format;
3948 out->sample_rate = config->sample_rate;
3949 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3950 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3951 out->handle = handle;
3952
3953 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3954 if (pcm_profile == NULL) {
3955 ret = -EINVAL;
3956 goto error_open;
3957 }
3958 out->config = pcm_profile->config;
3959
3960 /* Init use case and pcm_config */
3961 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3962 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3963 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3964 ALOGE("%s: Unsupported Offload information", __func__);
3965 ret = -EINVAL;
3966 goto error_open;
3967 }
3968 if (!is_supported_format(config->offload_info.format)) {
3969 ALOGE("%s: Unsupported audio format", __func__);
3970 ret = -EINVAL;
3971 goto error_open;
3972 }
3973
3974 out->compr_config.codec = (struct snd_codec *)
3975 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003976 if (out->compr_config.codec == NULL) {
3977 ret = -ENOMEM;
3978 goto error_open;
3979 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003980
3981 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3982 if (config->offload_info.channel_mask)
3983 out->channel_mask = config->offload_info.channel_mask;
3984 else if (config->channel_mask)
3985 out->channel_mask = config->channel_mask;
3986 out->format = config->offload_info.format;
3987 out->sample_rate = config->offload_info.sample_rate;
3988
3989 out->stream.set_callback = out_set_callback;
3990 out->stream.pause = out_pause;
3991 out->stream.resume = out_resume;
3992 out->stream.drain = out_drain;
3993 out->stream.flush = out_flush;
3994
3995 out->compr_config.codec->id =
3996 get_snd_codec_id(config->offload_info.format);
3997 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3998 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3999 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
4000 out->compr_config.codec->bit_rate =
4001 config->offload_info.bit_rate;
4002 out->compr_config.codec->ch_in =
4003 audio_channel_count_from_out_mask(config->channel_mask);
4004 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4005
4006 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4007 out->non_blocking = 1;
4008
4009 out->send_new_metadata = 1;
4010 create_offload_callback_thread(out);
4011 out->offload_state = OFFLOAD_STATE_IDLE;
4012
4013 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4014 __func__, config->offload_info.version,
4015 config->offload_info.bit_rate);
4016 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4017 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004018 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004019 out->sample_rate = out->config.rate;
4020 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4021 } else {
4022 out->usecase = USECASE_AUDIO_PLAYBACK;
4023 out->sample_rate = out->config.rate;
4024 }
4025
4026 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4027 if (adev->primary_output == NULL)
4028 adev->primary_output = out;
4029 else {
4030 ALOGE("%s: Primary output is already opened", __func__);
4031 ret = -EEXIST;
4032 goto error_open;
4033 }
4034 }
4035
4036 /* Check if this usecase is already existing */
4037 pthread_mutex_lock(&adev->lock);
4038 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4039 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4040 pthread_mutex_unlock(&adev->lock);
4041 ret = -EEXIST;
4042 goto error_open;
4043 }
4044 pthread_mutex_unlock(&adev->lock);
4045
4046 out->stream.common.get_sample_rate = out_get_sample_rate;
4047 out->stream.common.set_sample_rate = out_set_sample_rate;
4048 out->stream.common.get_buffer_size = out_get_buffer_size;
4049 out->stream.common.get_channels = out_get_channels;
4050 out->stream.common.get_format = out_get_format;
4051 out->stream.common.set_format = out_set_format;
4052 out->stream.common.standby = out_standby;
4053 out->stream.common.dump = out_dump;
4054 out->stream.common.set_parameters = out_set_parameters;
4055 out->stream.common.get_parameters = out_get_parameters;
4056 out->stream.common.add_audio_effect = out_add_audio_effect;
4057 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4058 out->stream.get_latency = out_get_latency;
4059 out->stream.set_volume = out_set_volume;
4060 out->stream.write = out_write;
4061 out->stream.get_render_position = out_get_render_position;
4062 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4063 out->stream.get_presentation_position = out_get_presentation_position;
4064
4065 out->standby = 1;
4066 /* out->muted = false; by calloc() */
4067 /* out->written = 0; by calloc() */
4068
4069 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4070 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4071 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4072
4073 config->format = out->stream.common.get_format(&out->stream.common);
4074 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4075 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4076
4077 out->is_fastmixer_affinity_set = false;
4078
4079 *stream_out = &out->stream;
4080 ALOGV("%s: exit", __func__);
4081 return 0;
4082
4083error_open:
4084 free(out);
4085 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004086error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004087 ALOGV("%s: exit: ret %d", __func__, ret);
4088 return ret;
4089}
4090
4091static void adev_close_output_stream(struct audio_hw_device *dev,
4092 struct audio_stream_out *stream)
4093{
4094 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004095 (void)dev;
4096
4097 ALOGV("%s: enter", __func__);
4098 out_standby(&stream->common);
4099 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4100 destroy_offload_callback_thread(out);
4101
4102 if (out->compr_config.codec != NULL)
4103 free(out->compr_config.codec);
4104 }
4105 pthread_cond_destroy(&out->cond);
4106 pthread_mutex_destroy(&out->lock);
4107 free(stream);
4108 ALOGV("%s: exit", __func__);
4109}
4110
4111static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4112{
4113 struct audio_device *adev = (struct audio_device *)dev;
4114 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004115 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004116#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004117 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004118#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004119 int ret;
4120
4121 ALOGV("%s: enter: %s", __func__, kvpairs);
4122
4123 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004124
Andreas Schneider05bc1882017-02-09 14:03:11 +01004125 /******************************************************
4126 *** BT SCO
4127 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004128 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4129 if (ret >= 0) {
4130 /* When set to false, HAL should disable EC and NS
4131 * But it is currently not supported.
4132 */
4133 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004134 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004135 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004136 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004137 }
4138
Andreas Schneider05bc1882017-02-09 14:03:11 +01004139 ret = str_parms_get_str(parms,
4140 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4141 value,
4142 sizeof(value));
4143 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01004144 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4145 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01004146 } else {
4147 adev->voice.bluetooth_wb = false;
4148 }
4149 }
4150
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004151 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4152 if (ret >= 0) {
4153 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4154 adev->screen_off = false;
4155 else
4156 adev->screen_off = true;
4157 }
4158
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004159#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004160 ret = str_parms_get_int(parms, "rotation", &val);
4161 if (ret >= 0) {
4162 bool reverse_speakers = false;
4163 switch(val) {
4164 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4165 relative to the user when the device is rotated 90deg from its default rotation. This
4166 assumption is device-specific, not platform-specific like this code. */
4167 case 270:
4168 reverse_speakers = true;
4169 break;
4170 case 0:
4171 case 90:
4172 case 180:
4173 break;
4174 default:
4175 ALOGE("%s: unexpected rotation of %d", __func__, val);
4176 }
4177 pthread_mutex_lock(&adev->lock);
4178 if (adev->speaker_lr_swap != reverse_speakers) {
4179 adev->speaker_lr_swap = reverse_speakers;
4180 /* only update the selected device if there is active pcm playback */
4181 struct audio_usecase *usecase;
4182 struct listnode *node;
4183 list_for_each(node, &adev->usecase_list) {
4184 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4185 if (usecase->type == PCM_PLAYBACK) {
4186 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004187 break;
4188 }
4189 }
4190 }
4191 pthread_mutex_unlock(&adev->lock);
4192 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004193#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004194
4195 str_parms_destroy(parms);
4196
4197 if (ret > 0)
4198 ret = 0;
4199
4200 ALOGV("%s: exit with code(%d)", __func__, ret);
4201 return ret;
4202}
4203
4204static char* adev_get_parameters(const struct audio_hw_device *dev,
4205 const char *keys)
4206{
4207 (void)dev;
4208 (void)keys;
4209
4210 return strdup("");
4211}
4212
4213static int adev_init_check(const struct audio_hw_device *dev)
4214{
4215 (void)dev;
4216
4217 return 0;
4218}
4219
4220static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4221{
4222 int ret = 0;
4223 struct audio_device *adev = (struct audio_device *)dev;
4224 pthread_mutex_lock(&adev->lock);
4225 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004226 adev->voice.volume = volume;
4227 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004228 pthread_mutex_unlock(&adev->lock);
4229 return ret;
4230}
4231
4232static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4233{
4234 (void)dev;
4235 (void)volume;
4236
4237 return -ENOSYS;
4238}
4239
4240static int adev_get_master_volume(struct audio_hw_device *dev,
4241 float *volume)
4242{
4243 (void)dev;
4244 (void)volume;
4245
4246 return -ENOSYS;
4247}
4248
4249static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4250{
4251 (void)dev;
4252 (void)muted;
4253
4254 return -ENOSYS;
4255}
4256
4257static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4258{
4259 (void)dev;
4260 (void)muted;
4261
4262 return -ENOSYS;
4263}
4264
4265static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4266{
4267 struct audio_device *adev = (struct audio_device *)dev;
4268
4269 pthread_mutex_lock(&adev->lock);
4270 if (adev->mode != mode) {
4271 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004272 if (amplifier_set_mode(mode) != 0) {
4273 ALOGE("Failed setting amplifier mode");
4274 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004275 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004276
4277 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4278 stop_voice_call(adev);
4279 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004280 }
4281 pthread_mutex_unlock(&adev->lock);
4282 return 0;
4283}
4284
4285static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4286{
4287 struct audio_device *adev = (struct audio_device *)dev;
4288 int err = 0;
4289
4290 pthread_mutex_lock(&adev->lock);
4291 adev->mic_mute = state;
4292
4293 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004294 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004295 }
4296
4297 pthread_mutex_unlock(&adev->lock);
4298 return err;
4299}
4300
4301static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4302{
4303 struct audio_device *adev = (struct audio_device *)dev;
4304
4305 *state = adev->mic_mute;
4306
4307 return 0;
4308}
4309
4310static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4311 const struct audio_config *config)
4312{
4313 (void)dev;
4314
4315 /* NOTE: we default to built in mic which may cause a mismatch between what we
4316 * report here and the actual buffer size
4317 */
4318 return get_input_buffer_size(config->sample_rate,
4319 config->format,
4320 audio_channel_count_from_in_mask(config->channel_mask),
4321 PCM_CAPTURE /* usecase_type */,
4322 AUDIO_DEVICE_IN_BUILTIN_MIC);
4323}
4324
4325static int adev_open_input_stream(struct audio_hw_device *dev,
4326 audio_io_handle_t handle __unused,
4327 audio_devices_t devices,
4328 struct audio_config *config,
4329 struct audio_stream_in **stream_in,
4330 audio_input_flags_t flags,
4331 const char *address __unused,
4332 audio_source_t source)
4333{
4334 struct audio_device *adev = (struct audio_device *)dev;
4335 struct stream_in *in;
4336 struct pcm_device_profile *pcm_profile;
4337
4338 ALOGV("%s: enter", __func__);
4339
4340 *stream_in = NULL;
4341 if (check_input_parameters(config->sample_rate, config->format,
4342 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4343 return -EINVAL;
4344
4345 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4346 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4347 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4348 pcm_profile = get_pcm_device(usecase_type, devices);
4349 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4350 // a low latency profile may not exist for that device, fall back
4351 // to regular capture. the MixerThread automatically changes
4352 // to non-fast capture based on the buffer size.
4353 flags &= ~AUDIO_INPUT_FLAG_FAST;
4354 usecase_type = PCM_CAPTURE;
4355 pcm_profile = get_pcm_device(usecase_type, devices);
4356 }
4357 if (pcm_profile == NULL)
4358 return -EINVAL;
4359
4360 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004361 if (in == NULL) {
4362 return -ENOMEM;
4363 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004364
4365 in->stream.common.get_sample_rate = in_get_sample_rate;
4366 in->stream.common.set_sample_rate = in_set_sample_rate;
4367 in->stream.common.get_buffer_size = in_get_buffer_size;
4368 in->stream.common.get_channels = in_get_channels;
4369 in->stream.common.get_format = in_get_format;
4370 in->stream.common.set_format = in_set_format;
4371 in->stream.common.standby = in_standby;
4372 in->stream.common.dump = in_dump;
4373 in->stream.common.set_parameters = in_set_parameters;
4374 in->stream.common.get_parameters = in_get_parameters;
4375 in->stream.common.add_audio_effect = in_add_audio_effect;
4376 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4377 in->stream.set_gain = in_set_gain;
4378 in->stream.read = in_read;
4379 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004380 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004381
4382 in->devices = devices;
4383 in->source = source;
4384 in->dev = adev;
4385 in->standby = 1;
4386 in->main_channels = config->channel_mask;
4387 in->requested_rate = config->sample_rate;
4388 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4389 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4390 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004391 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004392 /* HW codec is limited to default channels. No need to update with
4393 * requested channels */
4394 in->config = pcm_profile->config;
4395
4396 /* Update config params with the requested sample rate and channels */
4397 if (source == AUDIO_SOURCE_HOTWORD) {
4398 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4399 } else {
4400 in->usecase = USECASE_AUDIO_CAPTURE;
4401 }
4402 in->usecase_type = usecase_type;
4403
4404 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4405 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4406
4407 in->is_fastcapture_affinity_set = false;
4408
4409 *stream_in = &in->stream;
4410 ALOGV("%s: exit", __func__);
4411 return 0;
4412}
4413
4414static void adev_close_input_stream(struct audio_hw_device *dev,
4415 struct audio_stream_in *stream)
4416{
4417 struct audio_device *adev = (struct audio_device *)dev;
4418 struct stream_in *in = (struct stream_in*)stream;
4419 ALOGV("%s", __func__);
4420
4421 /* prevent concurrent out_set_parameters, or out_write from standby */
4422 pthread_mutex_lock(&adev->lock_inputs);
4423
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004424 if (in->read_buf) {
4425 free(in->read_buf);
4426 in->read_buf = NULL;
4427 }
4428
4429 if (in->resampler) {
4430 release_resampler(in->resampler);
4431 in->resampler = NULL;
4432 }
4433
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004434#ifdef PREPROCESSING_ENABLED
4435 int i;
4436
4437 for (i=0; i<in->num_preprocessors; i++) {
4438 free(in->preprocessors[i].channel_configs);
4439 }
4440
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004441 if (in->proc_buf_in) {
4442 free(in->proc_buf_in);
4443 in->proc_buf_in = NULL;
4444 }
4445
4446 if (in->proc_buf_out) {
4447 free(in->proc_buf_out);
4448 in->proc_buf_out = NULL;
4449 }
4450
4451 if (in->ref_buf) {
4452 free(in->ref_buf);
4453 in->ref_buf = NULL;
4454 }
4455
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004456#endif
4457
4458 in_standby_l(in);
4459 free(stream);
4460
4461 pthread_mutex_unlock(&adev->lock_inputs);
4462
4463 return;
4464}
4465
4466static int adev_dump(const audio_hw_device_t *device, int fd)
4467{
4468 (void)device;
4469 (void)fd;
4470
4471 return 0;
4472}
4473
4474static int adev_close(hw_device_t *device)
4475{
4476 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004477 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004478 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004479 if (audio_device_ref_count == 0) {
4480 if (amplifier_close() != 0) {
4481 ALOGE("Amplifier close failed");
4482 }
4483 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004484 free(adev->snd_dev_ref_cnt);
4485 free_mixer_list(adev);
4486 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004487
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004488 adev = NULL;
4489
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004490 return 0;
4491}
4492
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004493/* This returns true if the input parameter looks at all plausible as a low latency period size,
4494 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4495 * just that it _might_ work.
4496 */
4497static bool period_size_is_plausible_for_low_latency(int period_size)
4498{
4499 switch (period_size) {
4500 case 64:
4501 case 96:
4502 case 128:
4503 case 192:
4504 case 256:
4505 return true;
4506 default:
4507 return false;
4508 }
4509}
4510
4511static int adev_open(const hw_module_t *module, const char *name,
4512 hw_device_t **device)
4513{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004514 ALOGV("%s: enter", __func__);
4515 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4516
Andreas Schneider56204f62017-01-31 08:17:32 +01004517 *device = NULL;
4518
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004519 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004520 if (adev == NULL) {
4521 return -ENOMEM;
4522 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004523
4524 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4525 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4526 adev->device.common.module = (struct hw_module_t *)module;
4527 adev->device.common.close = adev_close;
4528
4529 adev->device.init_check = adev_init_check;
4530 adev->device.set_voice_volume = adev_set_voice_volume;
4531 adev->device.set_master_volume = adev_set_master_volume;
4532 adev->device.get_master_volume = adev_get_master_volume;
4533 adev->device.set_master_mute = adev_set_master_mute;
4534 adev->device.get_master_mute = adev_get_master_mute;
4535 adev->device.set_mode = adev_set_mode;
4536 adev->device.set_mic_mute = adev_set_mic_mute;
4537 adev->device.get_mic_mute = adev_get_mic_mute;
4538 adev->device.set_parameters = adev_set_parameters;
4539 adev->device.get_parameters = adev_get_parameters;
4540 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4541 adev->device.open_output_stream = adev_open_output_stream;
4542 adev->device.close_output_stream = adev_close_output_stream;
4543 adev->device.open_input_stream = adev_open_input_stream;
4544 adev->device.close_input_stream = adev_close_input_stream;
4545 adev->device.dump = adev_dump;
4546
4547 /* Set the default route before the PCM stream is opened */
4548 adev->mode = AUDIO_MODE_NORMAL;
4549 adev->active_input = NULL;
4550 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004551
4552 adev->voice.volume = 1.0f;
4553 adev->voice.bluetooth_nrec = true;
4554 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004555 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004556
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004557 /* adev->cur_hdmi_channels = 0; by calloc() */
4558 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004559 if (adev->snd_dev_ref_cnt == NULL) {
4560 free(adev);
4561 return -ENOMEM;
4562 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004563
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004564 adev->ns_in_voice_rec = false;
4565
4566 list_init(&adev->usecase_list);
4567
4568 if (mixer_init(adev) != 0) {
4569 free(adev->snd_dev_ref_cnt);
4570 free(adev);
4571 ALOGE("%s: Failed to init, aborting.", __func__);
4572 *device = NULL;
4573 return -EINVAL;
4574 }
4575
4576 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4577 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4578 if (adev->offload_fx_lib == NULL) {
4579 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4580 } else {
4581 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4582 adev->offload_fx_start_output =
4583 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4584 "visualizer_hal_start_output");
4585 adev->offload_fx_stop_output =
4586 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4587 "visualizer_hal_stop_output");
4588 }
4589 }
4590
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004591 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4592 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4593 if (adev->sound_trigger_lib == NULL) {
4594 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4595 } else {
4596 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4597 adev->sound_trigger_open_for_streaming =
4598 (int (*)(void))dlsym(adev->sound_trigger_lib,
4599 "sound_trigger_open_for_streaming");
4600 adev->sound_trigger_read_samples =
4601 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4602 "sound_trigger_read_samples");
4603 adev->sound_trigger_close_for_streaming =
4604 (int (*)(int))dlsym(adev->sound_trigger_lib,
4605 "sound_trigger_close_for_streaming");
4606 if (!adev->sound_trigger_open_for_streaming ||
4607 !adev->sound_trigger_read_samples ||
4608 !adev->sound_trigger_close_for_streaming) {
4609
4610 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4611 adev->sound_trigger_open_for_streaming = 0;
4612 adev->sound_trigger_read_samples = 0;
4613 adev->sound_trigger_close_for_streaming = 0;
4614 }
4615 }
4616 }
4617
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004618 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004619 if (adev->voice.session == NULL) {
4620 ALOGE("%s: Failed to initialize voice session data", __func__);
4621
4622 free(adev->snd_dev_ref_cnt);
4623 free(adev);
4624
4625 *device = NULL;
4626 return -EINVAL;
4627 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004628
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004629 if (amplifier_open() != 0) {
4630 ALOGE("Amplifier initialization failed");
4631 }
4632
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004633 *device = &adev->device.common;
4634
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004635 audio_device_ref_count++;
4636
4637 char value[PROPERTY_VALUE_MAX];
4638 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4639 int trial = atoi(value);
4640 if (period_size_is_plausible_for_low_latency(trial)) {
4641
4642 pcm_device_playback.config.period_size = trial;
4643 pcm_device_playback.config.start_threshold =
4644 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4645 pcm_device_playback.config.stop_threshold =
4646 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4647
4648 pcm_device_capture_low_latency.config.period_size = trial;
4649 }
4650 }
4651
4652 ALOGV("%s: exit", __func__);
4653 return 0;
4654}
4655
4656static struct hw_module_methods_t hal_module_methods = {
4657 .open = adev_open,
4658};
4659
4660struct audio_module HAL_MODULE_INFO_SYM = {
4661 .common = {
4662 .tag = HARDWARE_MODULE_TAG,
4663 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4664 .hal_api_version = HARDWARE_HAL_API_VERSION,
4665 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004666 .name = "Samsung Audio HAL",
4667 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004668 .methods = &hal_module_methods,
4669 },
4670};