blob: 9aa59899590ff7263d2d825f29d8cdb5c4dc0ef5 [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;
Victor Lourme5869cd32018-03-26 19:36:07 +02003306 int ret = -EINVAL;
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 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003345 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003346 }
3347 }
3348 }
3349 }
3350
Andreas Schneiderd6359182017-02-08 16:58:22 +01003351done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003352 pthread_mutex_unlock(&out->lock);
3353
3354 return ret;
3355}
3356
3357static int out_set_callback(struct audio_stream_out *stream,
3358 stream_callback_t callback, void *cookie)
3359{
3360 struct stream_out *out = (struct stream_out *)stream;
3361
3362 ALOGV("%s", __func__);
3363 lock_output_stream(out);
3364 out->offload_callback = callback;
3365 out->offload_cookie = cookie;
3366 pthread_mutex_unlock(&out->lock);
3367 return 0;
3368}
3369
3370static int out_pause(struct audio_stream_out* stream)
3371{
3372 struct stream_out *out = (struct stream_out *)stream;
3373 int status = -ENOSYS;
3374 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003375 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3376 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003377 return status;
3378}
3379
3380static int out_resume(struct audio_stream_out* stream)
3381{
3382 struct stream_out *out = (struct stream_out *)stream;
3383 int status = -ENOSYS;
3384 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003385 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3386 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003387 return status;
3388}
3389
3390static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3391{
3392 struct stream_out *out = (struct stream_out *)stream;
3393 int status = -ENOSYS;
3394 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003395 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3396 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003397 return status;
3398}
3399
3400static int out_flush(struct audio_stream_out* stream)
3401{
3402 struct stream_out *out = (struct stream_out *)stream;
3403 ALOGV("%s", __func__);
3404 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003405 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003406 }
3407 return -ENOSYS;
3408}
3409
3410/** audio_stream_in implementation **/
3411static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3412{
3413 struct stream_in *in = (struct stream_in *)stream;
3414
3415 return in->requested_rate;
3416}
3417
3418static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3419{
3420 (void)stream;
3421 (void)rate;
3422 return -ENOSYS;
3423}
3424
3425static uint32_t in_get_channels(const struct audio_stream *stream)
3426{
3427 struct stream_in *in = (struct stream_in *)stream;
3428
3429 return in->main_channels;
3430}
3431
3432static audio_format_t in_get_format(const struct audio_stream *stream)
3433{
3434 (void)stream;
3435 return AUDIO_FORMAT_PCM_16_BIT;
3436}
3437
3438static int in_set_format(struct audio_stream *stream, audio_format_t format)
3439{
3440 (void)stream;
3441 (void)format;
3442
3443 return -ENOSYS;
3444}
3445
3446static size_t in_get_buffer_size(const struct audio_stream *stream)
3447{
3448 struct stream_in *in = (struct stream_in *)stream;
3449
3450 return get_input_buffer_size(in->requested_rate,
3451 in_get_format(stream),
3452 audio_channel_count_from_in_mask(in->main_channels),
3453 in->usecase_type,
3454 in->devices);
3455}
3456
3457static int in_close_pcm_devices(struct stream_in *in)
3458{
3459 struct pcm_device *pcm_device;
3460 struct listnode *node;
3461 struct audio_device *adev = in->dev;
3462
3463 list_for_each(node, &in->pcm_dev_list) {
3464 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3465 if (pcm_device) {
3466 if (pcm_device->pcm)
3467 pcm_close(pcm_device->pcm);
3468 pcm_device->pcm = NULL;
3469 if (pcm_device->sound_trigger_handle > 0)
3470 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3471 pcm_device->sound_trigger_handle = 0;
3472 }
3473 }
3474 return 0;
3475}
3476
3477
3478/* must be called with stream and hw device mutex locked */
3479static int do_in_standby_l(struct stream_in *in)
3480{
3481 int status = 0;
3482
3483#ifdef PREPROCESSING_ENABLED
3484 struct audio_device *adev = in->dev;
3485#endif
3486 if (!in->standby) {
3487
3488 in_close_pcm_devices(in);
3489
3490#ifdef PREPROCESSING_ENABLED
3491 if (in->echo_reference != NULL) {
3492 /* stop reading from echo reference */
3493 in->echo_reference->read(in->echo_reference, NULL);
3494 put_echo_reference(adev, in->echo_reference);
3495 in->echo_reference = NULL;
3496 }
3497#ifdef HW_AEC_LOOPBACK
3498 if (in->hw_echo_reference)
3499 {
3500 if (in->hw_ref_buf) {
3501 free(in->hw_ref_buf);
3502 in->hw_ref_buf = NULL;
3503 }
3504 }
3505#endif // HW_AEC_LOOPBACK
3506#endif // PREPROCESSING_ENABLED
3507
3508 status = stop_input_stream(in);
3509
3510 if (in->read_buf) {
3511 free(in->read_buf);
3512 in->read_buf = NULL;
3513 }
3514
3515 in->standby = 1;
3516 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003517
3518 in->last_read_time_us = 0;
3519
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003520 return 0;
3521}
3522
3523// called with adev->lock_inputs locked
3524static int in_standby_l(struct stream_in *in)
3525{
3526 struct audio_device *adev = in->dev;
3527 int status = 0;
3528 lock_input_stream(in);
3529 if (!in->standby) {
3530 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003531 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003532 status = do_in_standby_l(in);
3533 pthread_mutex_unlock(&adev->lock);
3534 }
3535 pthread_mutex_unlock(&in->lock);
3536 return status;
3537}
3538
3539static int in_standby(struct audio_stream *stream)
3540{
3541 struct stream_in *in = (struct stream_in *)stream;
3542 struct audio_device *adev = in->dev;
3543 int status;
3544 ALOGV("%s: enter", __func__);
3545 pthread_mutex_lock(&adev->lock_inputs);
3546 status = in_standby_l(in);
3547 pthread_mutex_unlock(&adev->lock_inputs);
3548 ALOGV("%s: exit: status(%d)", __func__, status);
3549 return status;
3550}
3551
3552static int in_dump(const struct audio_stream *stream, int fd)
3553{
3554 (void)stream;
3555 (void)fd;
3556
3557 return 0;
3558}
3559
3560static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3561{
3562 struct stream_in *in = (struct stream_in *)stream;
3563 struct audio_device *adev = in->dev;
3564 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003565 char value[32];
3566 int ret, val = 0;
3567 struct audio_usecase *uc_info;
3568 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003569 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003570
3571 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3572 parms = str_parms_create_str(kvpairs);
3573
3574 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3575
3576 pthread_mutex_lock(&adev->lock_inputs);
3577 lock_input_stream(in);
3578 pthread_mutex_lock(&adev->lock);
3579 if (ret >= 0) {
3580 val = atoi(value);
3581 /* no audio source uses val == 0 */
3582 if (((int)in->source != val) && (val != 0)) {
3583 in->source = val;
3584 }
3585 }
3586
3587 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3588 if (ret >= 0) {
3589 val = atoi(value);
3590 if (((int)in->devices != val) && (val != 0)) {
3591 in->devices = val;
3592 /* If recording is in progress, change the tx device to new device */
3593 if (!in->standby) {
3594 uc_info = get_usecase_from_id(adev, in->usecase);
3595 if (uc_info == NULL) {
3596 ALOGE("%s: Could not find the usecase (%d) in the list",
3597 __func__, in->usecase);
3598 } else {
3599 if (list_empty(&in->pcm_dev_list))
3600 ALOGE("%s: pcm device list empty", __func__);
3601 else {
3602 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3603 struct pcm_device, stream_list_node);
3604 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3605 do_standby = true;
3606 }
3607 }
3608 }
3609 if (do_standby) {
3610 ret = do_in_standby_l(in);
3611 } else
3612 ret = select_devices(adev, in->usecase);
3613 }
3614 }
3615 }
3616 pthread_mutex_unlock(&adev->lock);
3617 pthread_mutex_unlock(&in->lock);
3618 pthread_mutex_unlock(&adev->lock_inputs);
3619 str_parms_destroy(parms);
3620
3621 if (ret > 0)
3622 ret = 0;
3623
3624 ALOGV("%s: exit: status(%d)", __func__, ret);
3625 return ret;
3626}
3627
3628static char* in_get_parameters(const struct audio_stream *stream,
3629 const char *keys)
3630{
3631 (void)stream;
3632 (void)keys;
3633
3634 return strdup("");
3635}
3636
3637static int in_set_gain(struct audio_stream_in *stream, float gain)
3638{
3639 (void)stream;
3640 (void)gain;
3641
3642 return 0;
3643}
3644
3645static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3646 size_t bytes)
3647{
3648 struct pcm_device *pcm_device;
3649 struct audio_device *adev = in->dev;
3650
3651 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3652 struct pcm_device, stream_list_node);
3653
3654 if (pcm_device->sound_trigger_handle > 0)
3655 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3656 else
3657 return 0;
3658}
3659
3660static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3661 size_t bytes)
3662{
3663 struct stream_in *in = (struct stream_in *)stream;
3664 struct audio_device *adev = in->dev;
3665 ssize_t frames = -1;
3666 int ret = -1;
3667 int read_and_process_successful = false;
3668
3669 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003670
3671 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3672 lock_input_stream(in);
3673
Andreas Schneider3b643832017-01-31 11:48:22 +01003674#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003675 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003676 pid_t tid = gettid();
3677 int err;
3678
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003679 err = fast_set_affinity(tid);
3680 if (err < 0) {
3681 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3682 }
3683 in->is_fastcapture_affinity_set = true;
3684 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003685#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003686
3687 if (in->standby) {
3688 pthread_mutex_unlock(&in->lock);
3689 pthread_mutex_lock(&adev->lock_inputs);
3690 lock_input_stream(in);
3691 if (!in->standby) {
3692 pthread_mutex_unlock(&adev->lock_inputs);
3693 goto false_alarm;
3694 }
3695 pthread_mutex_lock(&adev->lock);
3696 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003697 if (ret == 0) {
3698 amplifier_input_stream_start(stream);
3699 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003700 pthread_mutex_unlock(&adev->lock);
3701 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003702
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003703 if (ret != 0) {
3704 goto exit;
3705 }
3706 in->standby = 0;
3707 }
3708false_alarm:
3709
3710 if (!list_empty(&in->pcm_dev_list)) {
3711 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3712 bytes = read_bytes_from_dsp(in, buffer, bytes);
3713 if (bytes > 0)
3714 read_and_process_successful = true;
3715 } else {
3716 /*
3717 * Read PCM and:
3718 * - resample if needed
3719 * - process if pre-processors are attached
3720 * - discard unwanted channels
3721 */
3722 frames = read_and_process_frames(in, buffer, frames_rq);
3723 if (frames >= 0)
3724 read_and_process_successful = true;
3725 }
3726 }
3727
3728 /*
3729 * Instead of writing zeroes here, we could trust the hardware
3730 * to always provide zeroes when muted.
3731 */
3732 if (read_and_process_successful == true && adev->mic_mute)
3733 memset(buffer, 0, bytes);
3734
3735exit:
3736 pthread_mutex_unlock(&in->lock);
3737
3738 if (read_and_process_successful == false) {
3739 in_standby(&in->stream.common);
3740 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003741 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3742 clock_gettime(CLOCK_MONOTONIC, &t);
3743 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3744
3745 // we do a full sleep when exiting standby.
3746 const bool standby = in->last_read_time_us == 0;
3747 const int64_t elapsed_time_since_last_read = standby ?
3748 0 : now - in->last_read_time_us;
3749 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3750 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3751 if (sleep_time > 0) {
3752 usleep(sleep_time);
3753 } else {
3754 sleep_time = 0;
3755 }
3756 in->last_read_time_us = now + sleep_time;
3757 // last_read_time_us is an approximation of when the (simulated) alsa
3758 // buffer is drained by the read, and is empty.
3759 //
3760 // On the subsequent in_read(), we measure the elapsed time spent in
3761 // the recording thread. This is subtracted from the sleep estimate based on frames,
3762 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003763 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003764 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003765
3766 if (bytes > 0) {
3767 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3768 }
3769
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003770 return bytes;
3771}
3772
3773static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3774{
3775 (void)stream;
3776
3777 return 0;
3778}
3779
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003780static int in_get_capture_position(const struct audio_stream_in *stream,
3781 int64_t *frames, int64_t *time)
3782{
3783 if (stream == NULL || frames == NULL || time == NULL) {
3784 return -EINVAL;
3785 }
3786
3787 struct stream_in *in = (struct stream_in *)stream;
3788 struct pcm_device *pcm_device;
3789 int ret = -ENOSYS;
3790
3791 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3792 struct pcm_device, stream_list_node);
3793
3794 pthread_mutex_lock(&in->lock);
3795 if (pcm_device->pcm) {
3796 struct timespec timestamp;
3797 unsigned int avail;
3798 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3799 *frames = in->frames_read + avail;
3800 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3801 ret = 0;
3802 }
3803 }
3804
3805 pthread_mutex_unlock(&in->lock);
3806 return ret;
3807}
3808
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003809static int add_remove_audio_effect(const struct audio_stream *stream,
3810 effect_handle_t effect,
3811 bool enable)
3812{
3813 struct stream_in *in = (struct stream_in *)stream;
3814 struct audio_device *adev = in->dev;
3815 int status = 0;
3816 effect_descriptor_t desc;
3817#ifdef PREPROCESSING_ENABLED
3818 int i;
3819#endif
3820 status = (*effect)->get_descriptor(effect, &desc);
3821 if (status != 0)
3822 return status;
3823
3824 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3825
3826 pthread_mutex_lock(&adev->lock_inputs);
3827 lock_input_stream(in);
3828 pthread_mutex_lock(&in->dev->lock);
3829#ifndef PREPROCESSING_ENABLED
3830 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3831 in->enable_aec != enable &&
3832 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3833 in->enable_aec = enable;
3834 if (!in->standby)
3835 select_devices(in->dev, in->usecase);
3836 }
3837#else
3838 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3839 status = -ENOSYS;
3840 goto exit;
3841 }
3842 if ( enable == true ) {
3843 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3844 /* add the supported channel of the effect in the channel_configs */
3845 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3846 in->num_preprocessors ++;
3847 /* check compatibility between main channel supported and possible auxiliary channels */
3848 in_update_aux_channels(in, effect);//wesley crash
3849 in->aux_channels_changed = true;
3850 } else {
3851 /* if ( enable == false ) */
3852 if (in->num_preprocessors <= 0) {
3853 status = -ENOSYS;
3854 goto exit;
3855 }
3856 status = -EINVAL;
3857 for (i=0; i < in->num_preprocessors; i++) {
3858 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3859 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3860 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3861 in->preprocessors[i - 1].num_channel_configs =
3862 in->preprocessors[i].num_channel_configs;
3863 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3864 continue;
3865 }
3866 if ( in->preprocessors[i].effect_itfe == effect ) {
3867 ALOGV("add_remove_audio_effect found fx at index %d", i);
3868 free(in->preprocessors[i].channel_configs);
3869 status = 0;
3870 }
3871 }
3872 if (status != 0)
3873 goto exit;
3874 in->num_preprocessors--;
3875 /* if we remove one effect, at least the last proproc should be reset */
3876 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3877 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3878 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3879 in->aux_channels_changed = false;
3880 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3881 }
3882 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3883
3884 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3885 in->enable_aec = enable;
3886 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3887 if (!in->standby) {
3888 select_devices(in->dev, in->usecase);
3889 do_in_standby_l(in);
3890 }
3891 if (in->enable_aec == true) {
3892 in_configure_reverse(in);
3893 }
3894 }
3895exit:
3896#endif
3897 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3898 pthread_mutex_unlock(&in->dev->lock);
3899 pthread_mutex_unlock(&in->lock);
3900 pthread_mutex_unlock(&adev->lock_inputs);
3901 return status;
3902}
3903
3904static int in_add_audio_effect(const struct audio_stream *stream,
3905 effect_handle_t effect)
3906{
3907 ALOGV("%s: effect %p", __func__, effect);
3908 return add_remove_audio_effect(stream, effect, true);
3909}
3910
3911static int in_remove_audio_effect(const struct audio_stream *stream,
3912 effect_handle_t effect)
3913{
3914 ALOGV("%s: effect %p", __func__, effect);
3915 return add_remove_audio_effect(stream, effect, false);
3916}
3917
3918static int adev_open_output_stream(struct audio_hw_device *dev,
3919 audio_io_handle_t handle,
3920 audio_devices_t devices,
3921 audio_output_flags_t flags,
3922 struct audio_config *config,
3923 struct audio_stream_out **stream_out,
3924 const char *address __unused)
3925{
3926 struct audio_device *adev = (struct audio_device *)dev;
3927 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003928 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003929 struct pcm_device_profile *pcm_profile;
3930
3931 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3932 __func__, config->sample_rate, config->channel_mask, devices, flags);
3933 *stream_out = NULL;
3934 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003935 if (out == NULL) {
3936 ret = -ENOMEM;
3937 goto error_config;
3938 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003939
3940 if (devices == AUDIO_DEVICE_NONE)
3941 devices = AUDIO_DEVICE_OUT_SPEAKER;
3942
3943 out->flags = flags;
3944 out->devices = devices;
3945 out->dev = adev;
3946 out->format = config->format;
3947 out->sample_rate = config->sample_rate;
3948 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3949 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3950 out->handle = handle;
3951
3952 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3953 if (pcm_profile == NULL) {
3954 ret = -EINVAL;
3955 goto error_open;
3956 }
3957 out->config = pcm_profile->config;
3958
3959 /* Init use case and pcm_config */
3960 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3961 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3962 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3963 ALOGE("%s: Unsupported Offload information", __func__);
3964 ret = -EINVAL;
3965 goto error_open;
3966 }
3967 if (!is_supported_format(config->offload_info.format)) {
3968 ALOGE("%s: Unsupported audio format", __func__);
3969 ret = -EINVAL;
3970 goto error_open;
3971 }
3972
3973 out->compr_config.codec = (struct snd_codec *)
3974 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003975 if (out->compr_config.codec == NULL) {
3976 ret = -ENOMEM;
3977 goto error_open;
3978 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003979
3980 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3981 if (config->offload_info.channel_mask)
3982 out->channel_mask = config->offload_info.channel_mask;
3983 else if (config->channel_mask)
3984 out->channel_mask = config->channel_mask;
3985 out->format = config->offload_info.format;
3986 out->sample_rate = config->offload_info.sample_rate;
3987
3988 out->stream.set_callback = out_set_callback;
3989 out->stream.pause = out_pause;
3990 out->stream.resume = out_resume;
3991 out->stream.drain = out_drain;
3992 out->stream.flush = out_flush;
3993
3994 out->compr_config.codec->id =
3995 get_snd_codec_id(config->offload_info.format);
3996 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3997 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3998 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3999 out->compr_config.codec->bit_rate =
4000 config->offload_info.bit_rate;
4001 out->compr_config.codec->ch_in =
4002 audio_channel_count_from_out_mask(config->channel_mask);
4003 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4004
4005 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4006 out->non_blocking = 1;
4007
4008 out->send_new_metadata = 1;
4009 create_offload_callback_thread(out);
4010 out->offload_state = OFFLOAD_STATE_IDLE;
4011
4012 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4013 __func__, config->offload_info.version,
4014 config->offload_info.bit_rate);
4015 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4016 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004017 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004018 out->sample_rate = out->config.rate;
4019 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4020 } else {
4021 out->usecase = USECASE_AUDIO_PLAYBACK;
4022 out->sample_rate = out->config.rate;
4023 }
4024
4025 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4026 if (adev->primary_output == NULL)
4027 adev->primary_output = out;
4028 else {
4029 ALOGE("%s: Primary output is already opened", __func__);
4030 ret = -EEXIST;
4031 goto error_open;
4032 }
4033 }
4034
4035 /* Check if this usecase is already existing */
4036 pthread_mutex_lock(&adev->lock);
4037 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4038 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4039 pthread_mutex_unlock(&adev->lock);
4040 ret = -EEXIST;
4041 goto error_open;
4042 }
4043 pthread_mutex_unlock(&adev->lock);
4044
4045 out->stream.common.get_sample_rate = out_get_sample_rate;
4046 out->stream.common.set_sample_rate = out_set_sample_rate;
4047 out->stream.common.get_buffer_size = out_get_buffer_size;
4048 out->stream.common.get_channels = out_get_channels;
4049 out->stream.common.get_format = out_get_format;
4050 out->stream.common.set_format = out_set_format;
4051 out->stream.common.standby = out_standby;
4052 out->stream.common.dump = out_dump;
4053 out->stream.common.set_parameters = out_set_parameters;
4054 out->stream.common.get_parameters = out_get_parameters;
4055 out->stream.common.add_audio_effect = out_add_audio_effect;
4056 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4057 out->stream.get_latency = out_get_latency;
4058 out->stream.set_volume = out_set_volume;
4059 out->stream.write = out_write;
4060 out->stream.get_render_position = out_get_render_position;
4061 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4062 out->stream.get_presentation_position = out_get_presentation_position;
4063
4064 out->standby = 1;
4065 /* out->muted = false; by calloc() */
4066 /* out->written = 0; by calloc() */
4067
4068 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4069 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4070 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4071
4072 config->format = out->stream.common.get_format(&out->stream.common);
4073 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4074 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4075
4076 out->is_fastmixer_affinity_set = false;
4077
4078 *stream_out = &out->stream;
4079 ALOGV("%s: exit", __func__);
4080 return 0;
4081
4082error_open:
4083 free(out);
4084 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004085error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004086 ALOGV("%s: exit: ret %d", __func__, ret);
4087 return ret;
4088}
4089
4090static void adev_close_output_stream(struct audio_hw_device *dev,
4091 struct audio_stream_out *stream)
4092{
4093 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004094 (void)dev;
4095
4096 ALOGV("%s: enter", __func__);
4097 out_standby(&stream->common);
4098 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4099 destroy_offload_callback_thread(out);
4100
4101 if (out->compr_config.codec != NULL)
4102 free(out->compr_config.codec);
4103 }
4104 pthread_cond_destroy(&out->cond);
4105 pthread_mutex_destroy(&out->lock);
4106 free(stream);
4107 ALOGV("%s: exit", __func__);
4108}
4109
4110static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4111{
4112 struct audio_device *adev = (struct audio_device *)dev;
4113 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004114 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004115#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004116 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004117#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004118 int ret;
4119
4120 ALOGV("%s: enter: %s", __func__, kvpairs);
4121
4122 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004123
Andreas Schneider05bc1882017-02-09 14:03:11 +01004124 /******************************************************
4125 *** BT SCO
4126 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004127 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4128 if (ret >= 0) {
4129 /* When set to false, HAL should disable EC and NS
4130 * But it is currently not supported.
4131 */
4132 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004133 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004134 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004135 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004136 }
4137
Andreas Schneider05bc1882017-02-09 14:03:11 +01004138 ret = str_parms_get_str(parms,
4139 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4140 value,
4141 sizeof(value));
4142 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01004143 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4144 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01004145 } else {
4146 adev->voice.bluetooth_wb = false;
4147 }
4148 }
4149
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004150 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4151 if (ret >= 0) {
4152 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4153 adev->screen_off = false;
4154 else
4155 adev->screen_off = true;
4156 }
4157
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004158#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004159 ret = str_parms_get_int(parms, "rotation", &val);
4160 if (ret >= 0) {
4161 bool reverse_speakers = false;
4162 switch(val) {
4163 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4164 relative to the user when the device is rotated 90deg from its default rotation. This
4165 assumption is device-specific, not platform-specific like this code. */
4166 case 270:
4167 reverse_speakers = true;
4168 break;
4169 case 0:
4170 case 90:
4171 case 180:
4172 break;
4173 default:
4174 ALOGE("%s: unexpected rotation of %d", __func__, val);
4175 }
4176 pthread_mutex_lock(&adev->lock);
4177 if (adev->speaker_lr_swap != reverse_speakers) {
4178 adev->speaker_lr_swap = reverse_speakers;
4179 /* only update the selected device if there is active pcm playback */
4180 struct audio_usecase *usecase;
4181 struct listnode *node;
4182 list_for_each(node, &adev->usecase_list) {
4183 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4184 if (usecase->type == PCM_PLAYBACK) {
4185 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004186 break;
4187 }
4188 }
4189 }
4190 pthread_mutex_unlock(&adev->lock);
4191 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004192#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004193
4194 str_parms_destroy(parms);
4195
4196 if (ret > 0)
4197 ret = 0;
4198
4199 ALOGV("%s: exit with code(%d)", __func__, ret);
4200 return ret;
4201}
4202
4203static char* adev_get_parameters(const struct audio_hw_device *dev,
4204 const char *keys)
4205{
4206 (void)dev;
4207 (void)keys;
4208
4209 return strdup("");
4210}
4211
4212static int adev_init_check(const struct audio_hw_device *dev)
4213{
4214 (void)dev;
4215
4216 return 0;
4217}
4218
4219static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4220{
4221 int ret = 0;
4222 struct audio_device *adev = (struct audio_device *)dev;
4223 pthread_mutex_lock(&adev->lock);
4224 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004225 adev->voice.volume = volume;
4226 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004227 pthread_mutex_unlock(&adev->lock);
4228 return ret;
4229}
4230
4231static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4232{
4233 (void)dev;
4234 (void)volume;
4235
4236 return -ENOSYS;
4237}
4238
4239static int adev_get_master_volume(struct audio_hw_device *dev,
4240 float *volume)
4241{
4242 (void)dev;
4243 (void)volume;
4244
4245 return -ENOSYS;
4246}
4247
4248static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4249{
4250 (void)dev;
4251 (void)muted;
4252
4253 return -ENOSYS;
4254}
4255
4256static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4257{
4258 (void)dev;
4259 (void)muted;
4260
4261 return -ENOSYS;
4262}
4263
4264static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4265{
4266 struct audio_device *adev = (struct audio_device *)dev;
4267
4268 pthread_mutex_lock(&adev->lock);
4269 if (adev->mode != mode) {
4270 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004271 if (amplifier_set_mode(mode) != 0) {
4272 ALOGE("Failed setting amplifier mode");
4273 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004274 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004275
4276 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4277 stop_voice_call(adev);
4278 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004279 }
4280 pthread_mutex_unlock(&adev->lock);
4281 return 0;
4282}
4283
4284static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4285{
4286 struct audio_device *adev = (struct audio_device *)dev;
4287 int err = 0;
4288
4289 pthread_mutex_lock(&adev->lock);
4290 adev->mic_mute = state;
4291
4292 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004293 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004294 }
4295
4296 pthread_mutex_unlock(&adev->lock);
4297 return err;
4298}
4299
4300static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4301{
4302 struct audio_device *adev = (struct audio_device *)dev;
4303
4304 *state = adev->mic_mute;
4305
4306 return 0;
4307}
4308
4309static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4310 const struct audio_config *config)
4311{
4312 (void)dev;
4313
4314 /* NOTE: we default to built in mic which may cause a mismatch between what we
4315 * report here and the actual buffer size
4316 */
4317 return get_input_buffer_size(config->sample_rate,
4318 config->format,
4319 audio_channel_count_from_in_mask(config->channel_mask),
4320 PCM_CAPTURE /* usecase_type */,
4321 AUDIO_DEVICE_IN_BUILTIN_MIC);
4322}
4323
4324static int adev_open_input_stream(struct audio_hw_device *dev,
4325 audio_io_handle_t handle __unused,
4326 audio_devices_t devices,
4327 struct audio_config *config,
4328 struct audio_stream_in **stream_in,
4329 audio_input_flags_t flags,
4330 const char *address __unused,
4331 audio_source_t source)
4332{
4333 struct audio_device *adev = (struct audio_device *)dev;
4334 struct stream_in *in;
4335 struct pcm_device_profile *pcm_profile;
4336
4337 ALOGV("%s: enter", __func__);
4338
4339 *stream_in = NULL;
4340 if (check_input_parameters(config->sample_rate, config->format,
4341 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4342 return -EINVAL;
4343
4344 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4345 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4346 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4347 pcm_profile = get_pcm_device(usecase_type, devices);
4348 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4349 // a low latency profile may not exist for that device, fall back
4350 // to regular capture. the MixerThread automatically changes
4351 // to non-fast capture based on the buffer size.
4352 flags &= ~AUDIO_INPUT_FLAG_FAST;
4353 usecase_type = PCM_CAPTURE;
4354 pcm_profile = get_pcm_device(usecase_type, devices);
4355 }
4356 if (pcm_profile == NULL)
4357 return -EINVAL;
4358
4359 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004360 if (in == NULL) {
4361 return -ENOMEM;
4362 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004363
4364 in->stream.common.get_sample_rate = in_get_sample_rate;
4365 in->stream.common.set_sample_rate = in_set_sample_rate;
4366 in->stream.common.get_buffer_size = in_get_buffer_size;
4367 in->stream.common.get_channels = in_get_channels;
4368 in->stream.common.get_format = in_get_format;
4369 in->stream.common.set_format = in_set_format;
4370 in->stream.common.standby = in_standby;
4371 in->stream.common.dump = in_dump;
4372 in->stream.common.set_parameters = in_set_parameters;
4373 in->stream.common.get_parameters = in_get_parameters;
4374 in->stream.common.add_audio_effect = in_add_audio_effect;
4375 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4376 in->stream.set_gain = in_set_gain;
4377 in->stream.read = in_read;
4378 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004379 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004380
4381 in->devices = devices;
4382 in->source = source;
4383 in->dev = adev;
4384 in->standby = 1;
4385 in->main_channels = config->channel_mask;
4386 in->requested_rate = config->sample_rate;
4387 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4388 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4389 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004390 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004391 /* HW codec is limited to default channels. No need to update with
4392 * requested channels */
4393 in->config = pcm_profile->config;
4394
4395 /* Update config params with the requested sample rate and channels */
4396 if (source == AUDIO_SOURCE_HOTWORD) {
4397 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4398 } else {
4399 in->usecase = USECASE_AUDIO_CAPTURE;
4400 }
4401 in->usecase_type = usecase_type;
4402
4403 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4404 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4405
4406 in->is_fastcapture_affinity_set = false;
4407
4408 *stream_in = &in->stream;
4409 ALOGV("%s: exit", __func__);
4410 return 0;
4411}
4412
4413static void adev_close_input_stream(struct audio_hw_device *dev,
4414 struct audio_stream_in *stream)
4415{
4416 struct audio_device *adev = (struct audio_device *)dev;
4417 struct stream_in *in = (struct stream_in*)stream;
4418 ALOGV("%s", __func__);
4419
4420 /* prevent concurrent out_set_parameters, or out_write from standby */
4421 pthread_mutex_lock(&adev->lock_inputs);
4422
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004423 if (in->read_buf) {
4424 free(in->read_buf);
4425 in->read_buf = NULL;
4426 }
4427
4428 if (in->resampler) {
4429 release_resampler(in->resampler);
4430 in->resampler = NULL;
4431 }
4432
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004433#ifdef PREPROCESSING_ENABLED
4434 int i;
4435
4436 for (i=0; i<in->num_preprocessors; i++) {
4437 free(in->preprocessors[i].channel_configs);
4438 }
4439
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004440 if (in->proc_buf_in) {
4441 free(in->proc_buf_in);
4442 in->proc_buf_in = NULL;
4443 }
4444
4445 if (in->proc_buf_out) {
4446 free(in->proc_buf_out);
4447 in->proc_buf_out = NULL;
4448 }
4449
4450 if (in->ref_buf) {
4451 free(in->ref_buf);
4452 in->ref_buf = NULL;
4453 }
4454
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004455#endif
4456
4457 in_standby_l(in);
4458 free(stream);
4459
4460 pthread_mutex_unlock(&adev->lock_inputs);
4461
4462 return;
4463}
4464
4465static int adev_dump(const audio_hw_device_t *device, int fd)
4466{
4467 (void)device;
4468 (void)fd;
4469
4470 return 0;
4471}
4472
4473static int adev_close(hw_device_t *device)
4474{
4475 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004476 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004477 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004478 if (audio_device_ref_count == 0) {
4479 if (amplifier_close() != 0) {
4480 ALOGE("Amplifier close failed");
4481 }
4482 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004483 free(adev->snd_dev_ref_cnt);
4484 free_mixer_list(adev);
4485 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004486
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004487 adev = NULL;
4488
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004489 return 0;
4490}
4491
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004492/* This returns true if the input parameter looks at all plausible as a low latency period size,
4493 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4494 * just that it _might_ work.
4495 */
4496static bool period_size_is_plausible_for_low_latency(int period_size)
4497{
4498 switch (period_size) {
4499 case 64:
4500 case 96:
4501 case 128:
4502 case 192:
4503 case 256:
4504 return true;
4505 default:
4506 return false;
4507 }
4508}
4509
4510static int adev_open(const hw_module_t *module, const char *name,
4511 hw_device_t **device)
4512{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004513 ALOGV("%s: enter", __func__);
4514 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4515
Andreas Schneider56204f62017-01-31 08:17:32 +01004516 *device = NULL;
4517
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004518 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004519 if (adev == NULL) {
4520 return -ENOMEM;
4521 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004522
4523 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4524 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4525 adev->device.common.module = (struct hw_module_t *)module;
4526 adev->device.common.close = adev_close;
4527
4528 adev->device.init_check = adev_init_check;
4529 adev->device.set_voice_volume = adev_set_voice_volume;
4530 adev->device.set_master_volume = adev_set_master_volume;
4531 adev->device.get_master_volume = adev_get_master_volume;
4532 adev->device.set_master_mute = adev_set_master_mute;
4533 adev->device.get_master_mute = adev_get_master_mute;
4534 adev->device.set_mode = adev_set_mode;
4535 adev->device.set_mic_mute = adev_set_mic_mute;
4536 adev->device.get_mic_mute = adev_get_mic_mute;
4537 adev->device.set_parameters = adev_set_parameters;
4538 adev->device.get_parameters = adev_get_parameters;
4539 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4540 adev->device.open_output_stream = adev_open_output_stream;
4541 adev->device.close_output_stream = adev_close_output_stream;
4542 adev->device.open_input_stream = adev_open_input_stream;
4543 adev->device.close_input_stream = adev_close_input_stream;
4544 adev->device.dump = adev_dump;
4545
4546 /* Set the default route before the PCM stream is opened */
4547 adev->mode = AUDIO_MODE_NORMAL;
4548 adev->active_input = NULL;
4549 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004550
4551 adev->voice.volume = 1.0f;
4552 adev->voice.bluetooth_nrec = true;
4553 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004554 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004555
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004556 /* adev->cur_hdmi_channels = 0; by calloc() */
4557 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004558 if (adev->snd_dev_ref_cnt == NULL) {
4559 free(adev);
4560 return -ENOMEM;
4561 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004562
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004563 adev->ns_in_voice_rec = false;
4564
4565 list_init(&adev->usecase_list);
4566
4567 if (mixer_init(adev) != 0) {
4568 free(adev->snd_dev_ref_cnt);
4569 free(adev);
4570 ALOGE("%s: Failed to init, aborting.", __func__);
4571 *device = NULL;
4572 return -EINVAL;
4573 }
4574
4575 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4576 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4577 if (adev->offload_fx_lib == NULL) {
4578 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4579 } else {
4580 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4581 adev->offload_fx_start_output =
4582 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4583 "visualizer_hal_start_output");
4584 adev->offload_fx_stop_output =
4585 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4586 "visualizer_hal_stop_output");
4587 }
4588 }
4589
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004590 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4591 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4592 if (adev->sound_trigger_lib == NULL) {
4593 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4594 } else {
4595 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4596 adev->sound_trigger_open_for_streaming =
4597 (int (*)(void))dlsym(adev->sound_trigger_lib,
4598 "sound_trigger_open_for_streaming");
4599 adev->sound_trigger_read_samples =
4600 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4601 "sound_trigger_read_samples");
4602 adev->sound_trigger_close_for_streaming =
4603 (int (*)(int))dlsym(adev->sound_trigger_lib,
4604 "sound_trigger_close_for_streaming");
4605 if (!adev->sound_trigger_open_for_streaming ||
4606 !adev->sound_trigger_read_samples ||
4607 !adev->sound_trigger_close_for_streaming) {
4608
4609 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4610 adev->sound_trigger_open_for_streaming = 0;
4611 adev->sound_trigger_read_samples = 0;
4612 adev->sound_trigger_close_for_streaming = 0;
4613 }
4614 }
4615 }
4616
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004617 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004618 if (adev->voice.session == NULL) {
4619 ALOGE("%s: Failed to initialize voice session data", __func__);
4620
4621 free(adev->snd_dev_ref_cnt);
4622 free(adev);
4623
4624 *device = NULL;
4625 return -EINVAL;
4626 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004627
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004628 if (amplifier_open() != 0) {
4629 ALOGE("Amplifier initialization failed");
4630 }
4631
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004632 *device = &adev->device.common;
4633
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004634 audio_device_ref_count++;
4635
4636 char value[PROPERTY_VALUE_MAX];
4637 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4638 int trial = atoi(value);
4639 if (period_size_is_plausible_for_low_latency(trial)) {
4640
4641 pcm_device_playback.config.period_size = trial;
4642 pcm_device_playback.config.start_threshold =
4643 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4644 pcm_device_playback.config.stop_threshold =
4645 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4646
4647 pcm_device_capture_low_latency.config.period_size = trial;
4648 }
4649 }
4650
4651 ALOGV("%s: exit", __func__);
4652 return 0;
4653}
4654
4655static struct hw_module_methods_t hal_module_methods = {
4656 .open = adev_open,
4657};
4658
4659struct audio_module HAL_MODULE_INFO_SYM = {
4660 .common = {
4661 .tag = HARDWARE_MODULE_TAG,
4662 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4663 .hal_api_version = HARDWARE_HAL_API_VERSION,
4664 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004665 .name = "Samsung Audio HAL",
4666 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004667 .methods = &hal_module_methods,
4668 },
4669};