blob: ff6ba33481031cac5bbcde04c1808ab4818f4e22 [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,
927 snd_device_t snd_device,
928 bool update_mixer)
929{
930 struct mixer_card *mixer_card;
931 struct listnode *node;
932 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100933#ifdef DSP_POWEROFF_DELAY
934 struct timespec activation_time;
935 struct timespec elapsed_time;
936#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100937
938 if (snd_device_name == NULL)
939 return -EINVAL;
940
941 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
942 ALOGV("Request to enable combo device: enable individual devices\n");
943 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
944 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
945 return 0;
946 }
947 adev->snd_dev_ref_cnt[snd_device]++;
948 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
949 ALOGV("%s: snd_device(%d: %s) is already active",
950 __func__, snd_device, snd_device_name);
951 return 0;
952 }
953
954 ALOGV("%s: snd_device(%d: %s)", __func__,
955 snd_device, snd_device_name);
956
957 list_for_each(node, &uc_info->mixer_list) {
958 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100959
960#ifdef DSP_POWEROFF_DELAY
961 clock_gettime(CLOCK_MONOTONIC, &activation_time);
962
Andreas Schneider58735a92017-02-13 16:48:17 +0100963 elapsed_time = time_spec_diff(activation_time,
964 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100965 if (elapsed_time.tv_sec == 0) {
966 long elapsed_usec = elapsed_time.tv_nsec / 1000;
967
968 if (elapsed_usec < DSP_POWEROFF_DELAY) {
969 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
970 }
971 }
972 update_mixer = true;
973#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200974
975 amplifier_enable_devices(snd_device, true);
976
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100977 audio_route_apply_path(mixer_card->audio_route, snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100978 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100979 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +0100980 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100981 }
982
983 return 0;
984}
985
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100986int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100987 struct audio_usecase *uc_info,
988 snd_device_t snd_device,
989 bool update_mixer)
990{
991 struct mixer_card *mixer_card;
992 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100993 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100994 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100995 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100996
997 if (snd_device_name == NULL)
998 return -EINVAL;
999
1000 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
1001 ALOGV("Request to disable combo device: disable individual devices\n");
1002 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
1003 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
1004 return 0;
1005 }
1006
1007 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
1008 ALOGE("%s: device ref cnt is already 0", __func__);
1009 return -EINVAL;
1010 }
1011 adev->snd_dev_ref_cnt[snd_device]--;
1012 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
1013 ALOGV("%s: snd_device(%d: %s)", __func__,
1014 snd_device, snd_device_name);
1015 list_for_each(node, &uc_info->mixer_list) {
1016 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +01001017#ifdef DSP_POWEROFF_DELAY
1018 update_mixer = true;
1019#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001020 audio_route_reset_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +01001021 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +01001022 /*
1023 * Cycle the rx device to eliminate routing conflicts.
1024 * This prevents issues when an input route shares mixer controls with an output
1025 * route.
1026 */
1027 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
1028 audio_route_apply_path(mixer_card->audio_route, out_snd_device_name);
1029 }
Andreas Schneider759368f2017-02-02 16:11:14 +01001030 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001031 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +01001032 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001033
1034 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +01001035#ifdef DSP_POWEROFF_DELAY
1036 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
1037#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001038 }
1039 }
1040 return 0;
1041}
1042
1043static int select_devices(struct audio_device *adev,
1044 audio_usecase_t uc_id)
1045{
1046 snd_device_t out_snd_device = SND_DEVICE_NONE;
1047 snd_device_t in_snd_device = SND_DEVICE_NONE;
1048 struct audio_usecase *usecase = NULL;
1049 struct audio_usecase *vc_usecase = NULL;
1050 struct listnode *node;
1051 struct stream_in *active_input = NULL;
1052 struct stream_out *active_out;
1053 struct mixer_card *mixer_card;
1054
1055 ALOGV("%s: usecase(%d)", __func__, uc_id);
1056
1057 if (uc_id == USECASE_AUDIO_CAPTURE_HOTWORD)
1058 return 0;
1059
1060 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1061 if (usecase != NULL) {
1062 active_input = (struct stream_in *)usecase->stream;
1063 }
1064
1065 usecase = get_usecase_from_id(adev, uc_id);
1066 if (usecase == NULL) {
1067 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1068 return -EINVAL;
1069 }
1070 active_out = (struct stream_out *)usecase->stream;
1071
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001072
1073 /*
1074 * If the voice call is active, use the sound devices of voice call usecase
1075 * so that it would not result any device switch. All the usecases will
1076 * be switched to new device when select_devices() is called for voice call
1077 * usecase.
1078 */
1079 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1080 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1081 if (vc_usecase == NULL) {
1082 ALOGE("%s: Could not find the voice call usecase", __func__);
1083 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001084 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1085 get_snd_device_display_name(vc_usecase->out_snd_device),
1086 get_snd_device_display_name(vc_usecase->in_snd_device));
1087 usecase->devices = vc_usecase->devices;
1088 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001089 }
1090 }
1091
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001092 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001093 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001094 prepare_voice_session(adev->voice.session, active_out->devices);
1095 out_snd_device = get_output_snd_device(adev, active_out->devices);
1096 in_snd_device = get_input_snd_device(adev, active_out->devices);
1097 } else if (usecase->type == PCM_PLAYBACK) {
1098 usecase->devices = active_out->devices;
1099 in_snd_device = SND_DEVICE_NONE;
1100 if (out_snd_device == SND_DEVICE_NONE) {
1101 out_snd_device = get_output_snd_device(adev, active_out->devices);
1102 if (active_out == adev->primary_output &&
1103 active_input &&
1104 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1105 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001106 }
1107 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001108 } else if (usecase->type == PCM_CAPTURE) {
1109 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1110 out_snd_device = SND_DEVICE_NONE;
1111 if (in_snd_device == SND_DEVICE_NONE) {
1112 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1113 adev->primary_output && !adev->primary_output->standby) {
1114 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1115 } else {
1116 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001117 }
1118 }
1119 }
1120
1121 if (out_snd_device == usecase->out_snd_device &&
1122 in_snd_device == usecase->in_snd_device) {
1123 return 0;
1124 }
1125
1126 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1127 out_snd_device, get_snd_device_display_name(out_snd_device),
1128 in_snd_device, get_snd_device_display_name(in_snd_device));
1129
1130
1131 /* Disable current sound devices */
1132 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001133 disable_snd_device(adev, usecase, usecase->out_snd_device, false);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001134 }
1135
1136 if (usecase->in_snd_device != SND_DEVICE_NONE) {
1137 disable_snd_device(adev, usecase, usecase->in_snd_device, false);
1138 }
1139
1140 /* Enable new sound devices */
1141 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001142 /* We need to update the audio path if we switch the out devices */
1143 if (adev->voice.in_call) {
1144 set_voice_session_audio_path(adev->voice.session);
1145 }
1146
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001147 enable_snd_device(adev, usecase, out_snd_device, false);
1148 }
1149
1150 if (in_snd_device != SND_DEVICE_NONE) {
1151 enable_snd_device(adev, usecase, in_snd_device, false);
1152 }
1153
1154 list_for_each(node, &usecase->mixer_list) {
1155 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
1156 audio_route_update_mixer(mixer_card->audio_route);
1157 }
1158
1159 usecase->in_snd_device = in_snd_device;
1160 usecase->out_snd_device = out_snd_device;
1161
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001162 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1163 amplifier_set_input_devices(in_snd_device);
1164 amplifier_set_output_devices(out_snd_device);
1165
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001166 return 0;
1167}
1168
1169
1170static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1171static int do_in_standby_l(struct stream_in *in);
1172
1173#ifdef PREPROCESSING_ENABLED
1174static void get_capture_reference_delay(struct stream_in *in,
1175 size_t frames __unused,
1176 struct echo_reference_buffer *buffer)
1177{
1178 ALOGVV("%s: enter:)", __func__);
1179
1180 /* read frames available in kernel driver buffer */
1181 unsigned int kernel_frames;
1182 struct timespec tstamp;
1183 long buf_delay;
1184 long kernel_delay;
1185 long delay_ns;
1186 struct pcm_device *ref_device;
1187 long rsmp_delay = 0;
1188
1189 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1190 struct pcm_device, stream_list_node);
1191
1192 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1193 buffer->time_stamp.tv_sec = 0;
1194 buffer->time_stamp.tv_nsec = 0;
1195 buffer->delay_ns = 0;
1196 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1197 return;
1198 }
1199
1200 /* adjust render time stamp with delay added by current driver buffer.
1201 * Add the duration of current frame as we want the render time of the last
1202 * sample being written. */
1203
1204 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1205
1206 buffer->time_stamp = tstamp;
1207 buffer->delay_ns = kernel_delay;
1208
1209 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1210 " delay_ns: [%d] , frames:[%zd]",
1211 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1212}
1213
1214static void get_capture_delay(struct stream_in *in,
1215 size_t frames __unused,
1216 struct echo_reference_buffer *buffer)
1217{
1218 ALOGVV("%s: enter:)", __func__);
1219 /* read frames available in kernel driver buffer */
1220 unsigned int kernel_frames;
1221 struct timespec tstamp;
1222 long buf_delay;
1223 long rsmp_delay;
1224 long kernel_delay;
1225 long delay_ns;
1226 struct pcm_device *pcm_device;
1227
1228 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1229 struct pcm_device, stream_list_node);
1230
1231 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1232 buffer->time_stamp.tv_sec = 0;
1233 buffer->time_stamp.tv_nsec = 0;
1234 buffer->delay_ns = 0;
1235 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1236 return;
1237 }
1238
1239 /* read frames available in audio HAL input buffer
1240 * add number of frames being read as we want the capture time of first sample
1241 * in current buffer */
1242 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1243 * at requested sampling rate */
1244 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1245 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1246
1247 /* add delay introduced by resampler */
1248 rsmp_delay = 0;
1249 if (in->resampler) {
1250 rsmp_delay = in->resampler->delay_ns(in->resampler);
1251 }
1252
1253 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1254
1255 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1256
1257 buffer->time_stamp = tstamp;
1258 buffer->delay_ns = delay_ns;
1259 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1260 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1261 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1262 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1263 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1264 in->read_buf_frames, in->proc_buf_frames, frames);
1265}
1266
1267static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1268{
1269 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1270 struct echo_reference_buffer b;
1271 b.delay_ns = 0;
1272 struct pcm_device *pcm_device;
1273
1274 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1275 struct pcm_device, stream_list_node);
1276
1277 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1278 "b.frame_count = [%zd]",
1279 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1280 if (in->ref_buf_frames < frames) {
1281 if (in->ref_buf_size < frames) {
1282 in->ref_buf_size = frames;
1283 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1284 ALOG_ASSERT((in->ref_buf != NULL),
1285 "update_echo_reference() failed to reallocate ref_buf");
1286 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1287 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1288 }
1289 b.frame_count = frames - in->ref_buf_frames;
1290 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1291
1292 get_capture_delay(in, frames, &b);
1293
1294 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1295 {
1296 in->ref_buf_frames += b.frame_count;
1297 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1298 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1299 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1300 }
1301 } else
1302 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1303 return b.delay_ns;
1304}
1305
1306static int set_preprocessor_param(effect_handle_t handle,
1307 effect_param_t *param)
1308{
1309 uint32_t size = sizeof(int);
1310 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1311 param->vsize;
1312
1313 int status = (*handle)->command(handle,
1314 EFFECT_CMD_SET_PARAM,
1315 sizeof (effect_param_t) + psize,
1316 param,
1317 &size,
1318 &param->status);
1319 if (status == 0)
1320 status = param->status;
1321
1322 return status;
1323}
1324
1325static int set_preprocessor_echo_delay(effect_handle_t handle,
1326 int32_t delay_us)
1327{
1328 struct {
1329 effect_param_t param;
1330 uint32_t data_0;
1331 int32_t data_1;
1332 } buf;
1333 memset(&buf, 0, sizeof(buf));
1334
1335 buf.param.psize = sizeof(uint32_t);
1336 buf.param.vsize = sizeof(uint32_t);
1337 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1338 buf.data_1 = delay_us;
1339
1340 return set_preprocessor_param(handle, &buf.param);
1341}
1342
1343static void push_echo_reference(struct stream_in *in, size_t frames)
1344{
1345 ALOGVV("%s: enter:)", __func__);
1346 /* read frames from echo reference buffer and update echo delay
1347 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1348
1349 int32_t delay_us = update_echo_reference(in, frames)/1000;
1350 int32_t size_in_bytes = 0;
1351 int i;
1352 audio_buffer_t buf;
1353
1354 if (in->ref_buf_frames < frames)
1355 frames = in->ref_buf_frames;
1356
1357 buf.frameCount = frames;
1358 buf.raw = in->ref_buf;
1359
1360 for (i = 0; i < in->num_preprocessors; i++) {
1361 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1362 continue;
1363 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1364 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1365 &buf,
1366 NULL);
1367 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1368 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1369 }
1370
1371 in->ref_buf_frames -= buf.frameCount;
1372 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1373 __func__, in->ref_buf_frames, in->config.channels);
1374 if (in->ref_buf_frames) {
1375 memcpy(in->ref_buf,
1376 in->ref_buf + buf.frameCount * in->config.channels,
1377 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1378 }
1379}
1380
1381static void put_echo_reference(struct audio_device *adev,
1382 struct echo_reference_itfe *reference)
1383{
1384 ALOGV("%s: enter:)", __func__);
1385 int32_t prev_generation = adev->echo_reference_generation;
1386 struct stream_out *out = adev->primary_output;
1387
1388 if (adev->echo_reference != NULL &&
1389 reference == adev->echo_reference) {
1390 /* echo reference is taken from the low latency output stream used
1391 * for voice use cases */
1392 adev->echo_reference = NULL;
1393 android_atomic_inc(&adev->echo_reference_generation);
1394 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1395 // if the primary output is in standby or did not pick the echo reference yet
1396 // we can safely get rid of it here.
1397 // otherwise, out_write() or out_standby() will detect the change in echo reference
1398 // generation and release the echo reference owned by the stream.
1399 if ((out->echo_reference_generation != prev_generation) || out->standby)
1400 release_echo_reference(reference);
1401 } else {
1402 release_echo_reference(reference);
1403 }
1404 ALOGV("release_echo_reference");
1405 }
1406}
1407
1408static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1409 audio_format_t format __unused,
1410 uint32_t channel_count,
1411 uint32_t sampling_rate)
1412{
1413 ALOGV("%s: enter:)", __func__);
1414 put_echo_reference(adev, adev->echo_reference);
1415 /* echo reference is taken from the low latency output stream used
1416 * for voice use cases */
1417 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1418 !adev->primary_output->standby) {
1419 struct audio_stream *stream =
1420 &adev->primary_output->stream.common;
1421 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1422 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1423 ALOGV("Calling create_echo_reference");
1424 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1425 channel_count,
1426 sampling_rate,
1427 AUDIO_FORMAT_PCM_16_BIT,
1428 wr_channel_count,
1429 wr_sampling_rate,
1430 &adev->echo_reference);
1431 if (status == 0)
1432 android_atomic_inc(&adev->echo_reference_generation);
1433 }
1434 return adev->echo_reference;
1435}
1436
1437#ifdef HW_AEC_LOOPBACK
1438static int get_hw_echo_reference(struct stream_in *in)
1439{
1440 struct pcm_device_profile *ref_pcm_profile;
1441 struct pcm_device *ref_device;
1442 struct audio_device *adev = in->dev;
1443
1444 in->hw_echo_reference = false;
1445
1446 if (adev->primary_output!= NULL &&
1447 !adev->primary_output->standby &&
1448 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1449 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1450 struct audio_stream *stream = &adev->primary_output->stream.common;
1451
1452 // TODO: currently there is no low latency mode for aec reference.
1453 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1454 if (ref_pcm_profile == NULL) {
1455 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1456 __func__, pcm_device_capture_loopback_aec.devices);
1457 return -EINVAL;
1458 }
1459
1460 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001461 if (ref_device == NULL) {
1462 return -ENOMEM;
1463 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001464 ref_device->pcm_profile = ref_pcm_profile;
1465
1466 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1467 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1468
1469 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1470 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1471 pcm_close(ref_device->pcm);
1472 ref_device->pcm = NULL;
1473 return -EIO;
1474 }
1475 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1476
1477 in->hw_echo_reference = true;
1478
1479 ALOGV("%s: hw_echo_reference is true", __func__);
1480 }
1481
1482 return 0;
1483}
1484#endif
1485
1486static int get_playback_delay(struct stream_out *out,
1487 size_t frames,
1488 struct echo_reference_buffer *buffer)
1489{
1490 unsigned int kernel_frames;
1491 int status;
1492 int primary_pcm = 0;
1493 struct pcm_device *pcm_device;
1494
1495 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1496 struct pcm_device, stream_list_node);
1497
1498 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1499 if (status < 0) {
1500 buffer->time_stamp.tv_sec = 0;
1501 buffer->time_stamp.tv_nsec = 0;
1502 buffer->delay_ns = 0;
1503 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1504 "setting playbackTimestamp to 0");
1505 return status;
1506 }
1507
1508 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1509
1510 /* adjust render time stamp with delay added by current driver buffer.
1511 * Add the duration of current frame as we want the render time of the last
1512 * sample being written. */
1513 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1514 out->config.rate);
1515 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1516 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1517
1518 return 0;
1519}
1520
1521#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1522 do { \
1523 if (fct_status != 0) \
1524 status = fct_status; \
1525 else if (cmd_status != 0) \
1526 status = cmd_status; \
1527 } while(0)
1528
1529static int in_configure_reverse(struct stream_in *in)
1530{
1531 int32_t cmd_status;
1532 uint32_t size = sizeof(int);
1533 effect_config_t config;
1534 int32_t status = 0;
1535 int32_t fct_status = 0;
1536 int i;
1537 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1538 if (in->num_preprocessors > 0) {
1539 config.inputCfg.channels = in->main_channels;
1540 config.outputCfg.channels = in->main_channels;
1541 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1542 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1543 config.inputCfg.samplingRate = in->requested_rate;
1544 config.outputCfg.samplingRate = in->requested_rate;
1545 config.inputCfg.mask =
1546 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1547 config.outputCfg.mask =
1548 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1549
1550 for (i = 0; i < in->num_preprocessors; i++)
1551 {
1552 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1553 continue;
1554 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1555 in->preprocessors[i].effect_itfe,
1556 EFFECT_CMD_SET_CONFIG_REVERSE,
1557 sizeof(effect_config_t),
1558 &config,
1559 &size,
1560 &cmd_status);
1561 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1562 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1563 }
1564 }
1565 return status;
1566}
1567
1568#define MAX_NUM_CHANNEL_CONFIGS 10
1569
1570static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1571 struct effect_info_s *effect_info)
1572{
1573 /* size and format of the cmd are defined in hardware/audio_effect.h */
1574 effect_handle_t effect = effect_info->effect_itfe;
1575 uint32_t cmd_size = 2 * sizeof(uint32_t);
1576 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1577 /* reply = status + number of configs (n) + n x channel_config_t */
1578 uint32_t reply_size =
1579 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1580 int32_t reply[reply_size];
1581 int32_t cmd_status;
1582
1583 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1584 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1585 ALOG_ASSERT((effect_info->channel_configs == NULL),
1586 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1587
1588 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1589 * This error will be interpreted as if the effect supports the main_channels but does not
1590 * support any aux_channels */
1591 cmd_status = (*effect)->command(effect,
1592 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1593 cmd_size,
1594 (void*)&cmd,
1595 &reply_size,
1596 (void*)&reply);
1597
1598 if (cmd_status != 0) {
1599 ALOGV("in_read_audio_effect_channel_configs(): "
1600 "fx->command returned %d", cmd_status);
1601 return;
1602 }
1603
1604 if (reply[0] != 0) {
1605 ALOGW("in_read_audio_effect_channel_configs(): "
1606 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1607 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1608 return;
1609 }
1610
1611 /* the feature is not supported */
1612 ALOGV("in_read_audio_effect_channel_configs()(): "
1613 "Feature supported and adding %d channel configs to the list", reply[1]);
1614 effect_info->num_channel_configs = reply[1];
1615 effect_info->channel_configs =
1616 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1617 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1618}
1619
1620
1621#define NUM_IN_AUX_CNL_CONFIGS 2
1622static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1623 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1624 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1625};
1626static uint32_t in_get_aux_channels(struct stream_in *in)
1627{
1628 int i;
1629 channel_config_t new_chcfg = {0, 0};
1630
1631 if (in->num_preprocessors == 0)
1632 return 0;
1633
1634 /* do not enable dual mic configurations when capturing from other microphones than
1635 * main or sub */
1636 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1637 return 0;
1638
1639 /* retain most complex aux channels configuration compatible with requested main channels and
1640 * supported by audio driver and all pre processors */
1641 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1642 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1643 if (cur_chcfg->main_channels == in->main_channels) {
1644 size_t match_cnt;
1645 size_t idx_preproc;
1646 for (idx_preproc = 0, match_cnt = 0;
1647 /* no need to continue if at least one preprocessor doesn't match */
1648 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1649 idx_preproc++) {
1650 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1651 size_t idx_chcfg;
1652
1653 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1654 if (memcmp(effect_info->channel_configs + idx_chcfg,
1655 cur_chcfg,
1656 sizeof(channel_config_t)) == 0) {
1657 match_cnt++;
1658 break;
1659 }
1660 }
1661 }
1662 /* if all preprocessors match, we have a candidate */
1663 if (match_cnt == (size_t)in->num_preprocessors) {
1664 /* retain most complex aux channels configuration */
1665 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1666 new_chcfg = *cur_chcfg;
1667 }
1668 }
1669 }
1670 }
1671
1672 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1673
1674 return new_chcfg.aux_channels;
1675}
1676
1677static int in_configure_effect_channels(effect_handle_t effect,
1678 channel_config_t *channel_config)
1679{
1680 int status = 0;
1681 int fct_status;
1682 int32_t cmd_status;
1683 uint32_t reply_size;
1684 effect_config_t config;
1685 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1686
1687 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1688 channel_config->main_channels,
1689 channel_config->aux_channels);
1690
1691 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1692 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1693 reply_size = sizeof(effect_config_t);
1694 fct_status = (*effect)->command(effect,
1695 EFFECT_CMD_GET_CONFIG,
1696 0,
1697 NULL,
1698 &reply_size,
1699 &config);
1700 if (fct_status != 0) {
1701 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1702 return fct_status;
1703 }
1704
1705 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1706 config.outputCfg.channels = config.inputCfg.channels;
1707 reply_size = sizeof(uint32_t);
1708 fct_status = (*effect)->command(effect,
1709 EFFECT_CMD_SET_CONFIG,
1710 sizeof(effect_config_t),
1711 &config,
1712 &reply_size,
1713 &cmd_status);
1714 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1715
1716 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1717 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1718 reply_size = sizeof(uint32_t);
1719 fct_status = (*effect)->command(effect,
1720 EFFECT_CMD_SET_FEATURE_CONFIG,
1721 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1722 cmd,
1723 &reply_size,
1724 &cmd_status);
1725 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1726
1727 /* some implementations need to be re-enabled after a config change */
1728 reply_size = sizeof(uint32_t);
1729 fct_status = (*effect)->command(effect,
1730 EFFECT_CMD_ENABLE,
1731 0,
1732 NULL,
1733 &reply_size,
1734 &cmd_status);
1735 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1736
1737 return status;
1738}
1739
1740static int in_reconfigure_channels(struct stream_in *in,
1741 effect_handle_t effect,
1742 channel_config_t *channel_config,
1743 bool config_changed) {
1744
1745 int status = 0;
1746
1747 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1748 config_changed, effect);
1749
1750 /* if config changed, reconfigure all previously added effects */
1751 if (config_changed) {
1752 int i;
1753 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1754 for (i = 0; i < in->num_preprocessors; i++)
1755 {
1756 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1757 channel_config);
1758 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1759 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1760 if (cur_status != 0) {
1761 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1762 "%d with channels: [%04x][%04x]",
1763 cur_status,
1764 i,
1765 channel_config->main_channels,
1766 channel_config->aux_channels);
1767 status = cur_status;
1768 }
1769 }
1770 } else if (effect != NULL && channel_config->aux_channels) {
1771 /* if aux channels config did not change but aux channels are present,
1772 * we still need to configure the effect being added */
1773 status = in_configure_effect_channels(effect, channel_config);
1774 }
1775 return status;
1776}
1777
1778static void in_update_aux_channels(struct stream_in *in,
1779 effect_handle_t effect)
1780{
1781 uint32_t aux_channels;
1782 channel_config_t channel_config;
1783 int status;
1784
1785 aux_channels = in_get_aux_channels(in);
1786
1787 channel_config.main_channels = in->main_channels;
1788 channel_config.aux_channels = aux_channels;
1789 status = in_reconfigure_channels(in,
1790 effect,
1791 &channel_config,
1792 (aux_channels != in->aux_channels));
1793
1794 if (status != 0) {
1795 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1796 /* resetting aux channels configuration */
1797 aux_channels = 0;
1798 channel_config.aux_channels = 0;
1799 in_reconfigure_channels(in, effect, &channel_config, true);
1800 }
1801 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1802 if (in->aux_channels != aux_channels) {
1803 in->aux_channels_changed = true;
1804 in->aux_channels = aux_channels;
1805 do_in_standby_l(in);
1806 }
1807}
1808#endif
1809
1810/* This function reads PCM data and:
1811 * - resample if needed
1812 * - process if pre-processors are attached
1813 * - discard unwanted channels
1814 */
1815static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1816{
1817 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001818 size_t src_channels = in->config.channels;
1819 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1820 int i;
1821 void *proc_buf_out;
1822 struct pcm_device *pcm_device;
1823 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1824#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001825 audio_buffer_t in_buf;
1826 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001827 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1828#endif
1829
1830 /* Additional channels might be added on top of main_channels:
1831 * - aux_channels (by processing effects)
1832 * - extra channels due to HW limitations
1833 * In case of additional channels, we cannot work inplace
1834 */
1835 if (has_additional_channels)
1836 proc_buf_out = in->proc_buf_out;
1837 else
1838 proc_buf_out = buffer;
1839
1840 if (list_empty(&in->pcm_dev_list)) {
1841 ALOGE("%s: pcm device list empty", __func__);
1842 return -EINVAL;
1843 }
1844
1845 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1846 struct pcm_device, stream_list_node);
1847
1848#ifdef PREPROCESSING_ENABLED
1849 if (has_processing) {
1850 /* since all the processing below is done in frames and using the config.channels
1851 * as the number of channels, no changes is required in case aux_channels are present */
1852 while (frames_wr < frames) {
1853 /* first reload enough frames at the end of process input buffer */
1854 if (in->proc_buf_frames < (size_t)frames) {
1855 ssize_t frames_rd;
1856 if (in->proc_buf_size < (size_t)frames) {
1857 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1858 in->proc_buf_size = (size_t)frames;
1859 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1860 ALOG_ASSERT((in->proc_buf_in != NULL),
1861 "process_frames() failed to reallocate proc_buf_in");
1862 if (has_additional_channels) {
1863 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1864 ALOG_ASSERT((in->proc_buf_out != NULL),
1865 "process_frames() failed to reallocate proc_buf_out");
1866 proc_buf_out = in->proc_buf_out;
1867 }
1868 }
1869 frames_rd = read_frames(in,
1870 in->proc_buf_in +
1871 in->proc_buf_frames * in->config.channels,
1872 frames - in->proc_buf_frames);
1873 if (frames_rd < 0) {
1874 /* Return error code */
1875 frames_wr = frames_rd;
1876 break;
1877 }
1878 in->proc_buf_frames += frames_rd;
1879 }
1880
1881 if (in->echo_reference != NULL) {
1882 push_echo_reference(in, in->proc_buf_frames);
1883 }
1884
1885 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1886 * the maximum number of frames to be consumed and produced by process() */
1887 in_buf.frameCount = in->proc_buf_frames;
1888 in_buf.s16 = in->proc_buf_in;
1889 out_buf.frameCount = frames - frames_wr;
1890 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1891
1892 /* FIXME: this works because of current pre processing library implementation that
1893 * does the actual process only when the last enabled effect process is called.
1894 * The generic solution is to have an output buffer for each effect and pass it as
1895 * input to the next.
1896 */
1897 for (i = 0; i < in->num_preprocessors; i++) {
1898 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1899 &in_buf,
1900 &out_buf);
1901 }
1902
1903 /* process() has updated the number of frames consumed and produced in
1904 * in_buf.frameCount and out_buf.frameCount respectively
1905 * move remaining frames to the beginning of in->proc_buf_in */
1906 in->proc_buf_frames -= in_buf.frameCount;
1907
1908 if (in->proc_buf_frames) {
1909 memcpy(in->proc_buf_in,
1910 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1911 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1912 }
1913
1914 /* if not enough frames were passed to process(), read more and retry. */
1915 if (out_buf.frameCount == 0) {
1916 ALOGW("No frames produced by preproc");
1917 continue;
1918 }
1919
1920 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1921 frames_wr += out_buf.frameCount;
1922 } else {
1923 /* The effect does not comply to the API. In theory, we should never end up here! */
1924 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1925 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1926 frames_wr = frames;
1927 }
1928 }
1929 }
1930 else
1931#endif //PREPROCESSING_ENABLED
1932 {
1933 /* No processing effects attached */
1934 if (has_additional_channels) {
1935 /* With additional channels, we cannot use original buffer */
1936 if (in->proc_buf_size < (size_t)frames) {
1937 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1938 in->proc_buf_size = (size_t)frames;
1939 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1940 ALOG_ASSERT((in->proc_buf_out != NULL),
1941 "process_frames() failed to reallocate proc_buf_out");
1942 proc_buf_out = in->proc_buf_out;
1943 }
1944 }
1945 frames_wr = read_frames(in, proc_buf_out, frames);
1946 }
1947
1948 /* Remove all additional channels that have been added on top of main_channels:
1949 * - aux_channels
1950 * - extra channels from HW due to HW limitations
1951 * Assumption is made that the channels are interleaved and that the main
1952 * channels are first. */
1953
1954 if (has_additional_channels)
1955 {
1956 int16_t* src_buffer = (int16_t *)proc_buf_out;
1957 int16_t* dst_buffer = (int16_t *)buffer;
1958
1959 if (dst_channels == 1) {
1960 for (i = frames_wr; i > 0; i--)
1961 {
1962 *dst_buffer++ = *src_buffer;
1963 src_buffer += src_channels;
1964 }
1965 } else {
1966 for (i = frames_wr; i > 0; i--)
1967 {
1968 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1969 dst_buffer += dst_channels;
1970 src_buffer += src_channels;
1971 }
1972 }
1973 }
1974
1975 return frames_wr;
1976}
1977
1978static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1979 struct resampler_buffer* buffer)
1980{
1981 struct stream_in *in;
1982 struct pcm_device *pcm_device;
1983
1984 if (buffer_provider == NULL || buffer == NULL)
1985 return -EINVAL;
1986
1987 in = (struct stream_in *)((char *)buffer_provider -
1988 offsetof(struct stream_in, buf_provider));
1989
1990 if (list_empty(&in->pcm_dev_list)) {
1991 buffer->raw = NULL;
1992 buffer->frame_count = 0;
1993 in->read_status = -ENODEV;
1994 return -ENODEV;
1995 }
1996
1997 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1998 struct pcm_device, stream_list_node);
1999
2000 if (in->read_buf_frames == 0) {
2001 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
2002 if (in->read_buf_size < in->config.period_size) {
2003 in->read_buf_size = in->config.period_size;
2004 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
2005 ALOG_ASSERT((in->read_buf != NULL),
2006 "get_next_buffer() failed to reallocate read_buf");
2007 }
2008
2009 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
2010
2011 if (in->read_status != 0) {
2012 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
2013 buffer->raw = NULL;
2014 buffer->frame_count = 0;
2015 return in->read_status;
2016 }
2017 in->read_buf_frames = in->config.period_size;
2018
2019#ifdef PREPROCESSING_ENABLED
2020#ifdef HW_AEC_LOOPBACK
2021 if (in->hw_echo_reference) {
2022 struct pcm_device *temp_device = NULL;
2023 struct pcm_device *ref_device = NULL;
2024 struct listnode *node = NULL;
2025 struct echo_reference_buffer b;
2026 size_t size_hw_ref_bytes;
2027 size_t size_hw_ref_frames;
2028 int read_status = 0;
2029
2030 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
2031 struct pcm_device, stream_list_node);
2032 list_for_each(node, &in->pcm_dev_list) {
2033 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
2034 if (temp_device->pcm_profile->id == 1) {
2035 ref_device = temp_device;
2036 break;
2037 }
2038 }
2039 if (ref_device) {
2040 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
2041 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
2042 if (in->hw_ref_buf_size < size_hw_ref_frames) {
2043 in->hw_ref_buf_size = size_hw_ref_frames;
2044 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2045 ALOG_ASSERT((in->hw_ref_buf != NULL),
2046 "get_next_buffer() failed to reallocate hw_ref_buf");
2047 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2048 in->hw_ref_buf, size_hw_ref_bytes);
2049 }
2050
2051 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2052 if (read_status != 0) {
2053 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2054 b.raw = NULL;
2055 b.frame_count = 0;
2056 }
2057 else {
2058 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2059 b.raw = (void *)in->hw_ref_buf;
2060 b.frame_count = size_hw_ref_frames;
2061 if (b.delay_ns != 0)
2062 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2063 in->echo_reference->write(in->echo_reference, &b);
2064 }
2065 }
2066 }
2067#endif // HW_AEC_LOOPBACK
2068#endif // PREPROCESSING_ENABLED
2069 }
2070
2071 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2072 in->read_buf_frames : buffer->frame_count;
2073 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2074 in->config.channels;
2075 return in->read_status;
2076}
2077
2078static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2079 struct resampler_buffer* buffer)
2080{
2081 struct stream_in *in;
2082
2083 if (buffer_provider == NULL || buffer == NULL)
2084 return;
2085
2086 in = (struct stream_in *)((char *)buffer_provider -
2087 offsetof(struct stream_in, buf_provider));
2088
2089 in->read_buf_frames -= buffer->frame_count;
2090}
2091
2092/* read_frames() reads frames from kernel driver, down samples to capture rate
2093 * if necessary and output the number of frames requested to the buffer specified */
2094static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2095{
2096 ssize_t frames_wr = 0;
2097
2098 struct pcm_device *pcm_device;
2099
2100 if (list_empty(&in->pcm_dev_list)) {
2101 ALOGE("%s: pcm device list empty", __func__);
2102 return -EINVAL;
2103 }
2104
2105 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2106 struct pcm_device, stream_list_node);
2107
2108 while (frames_wr < frames) {
2109 size_t frames_rd = frames - frames_wr;
2110 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2111 __func__,frames_rd,frames_wr,in->config.channels);
2112 if (in->resampler != NULL) {
2113 in->resampler->resample_from_provider(in->resampler,
2114 (int16_t *)((char *)buffer +
2115 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2116 &frames_rd);
2117 } else {
2118 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002119 .raw = NULL,
2120 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002121 };
2122 get_next_buffer(&in->buf_provider, &buf);
2123 if (buf.raw != NULL) {
2124 memcpy((char *)buffer +
2125 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2126 buf.raw,
2127 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2128 frames_rd = buf.frame_count;
2129 }
2130 release_buffer(&in->buf_provider, &buf);
2131 }
2132 /* in->read_status is updated by getNextBuffer() also called by
2133 * in->resampler->resample_from_provider() */
2134 if (in->read_status != 0)
2135 return in->read_status;
2136
2137 frames_wr += frames_rd;
2138 }
2139 return frames_wr;
2140}
2141
2142static int in_release_pcm_devices(struct stream_in *in)
2143{
2144 struct pcm_device *pcm_device;
2145 struct listnode *node;
2146 struct listnode *next;
2147
2148 list_for_each_safe(node, next, &in->pcm_dev_list) {
2149 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2150 list_remove(node);
2151 free(pcm_device);
2152 }
2153
2154 return 0;
2155}
2156
2157static int stop_input_stream(struct stream_in *in)
2158{
2159 struct audio_usecase *uc_info;
2160 struct audio_device *adev = in->dev;
2161
2162 adev->active_input = NULL;
2163 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2164 in->usecase, use_case_table[in->usecase]);
2165 uc_info = get_usecase_from_id(adev, in->usecase);
2166 if (uc_info == NULL) {
2167 ALOGE("%s: Could not find the usecase (%d) in the list",
2168 __func__, in->usecase);
2169 return -EINVAL;
2170 }
2171
2172 /* Disable the tx device */
2173 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2174
2175 list_remove(&uc_info->adev_list_node);
2176 free(uc_info);
2177
2178 if (list_empty(&in->pcm_dev_list)) {
2179 ALOGE("%s: pcm device list empty", __func__);
2180 return -EINVAL;
2181 }
2182
2183 in_release_pcm_devices(in);
2184 list_init(&in->pcm_dev_list);
2185
2186#ifdef HW_AEC_LOOPBACK
2187 if (in->hw_echo_reference)
2188 {
2189 in->hw_echo_reference = false;
2190 }
2191#endif
2192
2193 ALOGV("%s: exit", __func__);
2194 return 0;
2195}
2196
2197static int start_input_stream(struct stream_in *in)
2198{
2199 /* Enable output device and stream routing controls */
2200 int ret = 0;
2201 bool recreate_resampler = false;
2202 struct audio_usecase *uc_info;
2203 struct audio_device *adev = in->dev;
2204 struct pcm_device_profile *pcm_profile;
2205 struct pcm_device *pcm_device;
2206
2207 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2208 adev->active_input = in;
2209 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2210 if (pcm_profile == NULL) {
2211 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2212 __func__, in->usecase);
2213 ret = -EINVAL;
2214 goto error_config;
2215 }
2216
2217 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002218 if (uc_info == NULL) {
2219 ret = -ENOMEM;
2220 goto error_config;
2221 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002222 uc_info->id = in->usecase;
2223 uc_info->type = PCM_CAPTURE;
2224 uc_info->stream = (struct audio_stream *)in;
2225 uc_info->devices = in->devices;
2226 uc_info->in_snd_device = SND_DEVICE_NONE;
2227 uc_info->out_snd_device = SND_DEVICE_NONE;
2228
2229 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002230 if (pcm_device == NULL) {
2231 free(uc_info);
2232 ret = -ENOMEM;
2233 goto error_config;
2234 }
2235
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002236 pcm_device->pcm_profile = pcm_profile;
2237 list_init(&in->pcm_dev_list);
2238 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2239
2240 list_init(&uc_info->mixer_list);
2241 list_add_tail(&uc_info->mixer_list,
2242 &adev_get_mixer_for_card(adev,
2243 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2244
2245 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2246
2247 select_devices(adev, in->usecase);
2248
2249 /* Config should be updated as profile can be changed between different calls
2250 * to this function:
2251 * - Trigger resampler creation
2252 * - Config needs to be updated */
2253 if (in->config.rate != pcm_profile->config.rate) {
2254 recreate_resampler = true;
2255 }
2256 in->config = pcm_profile->config;
2257
2258#ifdef PREPROCESSING_ENABLED
2259 if (in->aux_channels_changed) {
2260 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2261 recreate_resampler = true;
2262 }
2263#endif
2264
2265 if (in->requested_rate != in->config.rate) {
2266 recreate_resampler = true;
2267 }
2268
2269 if (recreate_resampler) {
2270 if (in->resampler) {
2271 release_resampler(in->resampler);
2272 in->resampler = NULL;
2273 }
2274 in->buf_provider.get_next_buffer = get_next_buffer;
2275 in->buf_provider.release_buffer = release_buffer;
2276 ret = create_resampler(in->config.rate,
2277 in->requested_rate,
2278 in->config.channels,
2279 RESAMPLER_QUALITY_DEFAULT,
2280 &in->buf_provider,
2281 &in->resampler);
2282 }
2283
2284#ifdef PREPROCESSING_ENABLED
2285 if (in->enable_aec && in->echo_reference == NULL) {
2286 in->echo_reference = get_echo_reference(adev,
2287 AUDIO_FORMAT_PCM_16_BIT,
2288 audio_channel_count_from_in_mask(in->main_channels),
2289 in->requested_rate
2290 );
2291 }
2292
2293#ifdef HW_AEC_LOOPBACK
2294 if (in->enable_aec) {
2295 ret = get_hw_echo_reference(in);
2296 if (ret!=0)
2297 goto error_open;
2298
2299 /* force ref buffer reallocation */
2300 in->hw_ref_buf_size = 0;
2301 }
2302#endif
2303#endif
2304
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002305 if (in->dev->voice.in_call) {
2306 ALOGV("%s: in_call, not handling PCMs", __func__);
2307 goto skip_pcm_handling;
2308 }
2309
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002310 /* Open the PCM device.
2311 * The HW is limited to support only the default pcm_profile settings.
2312 * As such a change in aux_channels will not have an effect.
2313 */
2314 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2315 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2316 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2317 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2318
2319 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2320 if (!adev->sound_trigger_open_for_streaming) {
2321 ALOGE("%s: No handle to sound trigger HAL", __func__);
2322 ret = -EIO;
2323 goto error_open;
2324 }
2325 pcm_device->pcm = NULL;
2326 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2327 if (pcm_device->sound_trigger_handle <= 0) {
2328 ALOGE("%s: Failed to open DSP for streaming", __func__);
2329 ret = -EIO;
2330 goto error_open;
2331 }
2332 ALOGV("Opened DSP successfully");
2333 } else {
2334 pcm_device->sound_trigger_handle = 0;
2335 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2336 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2337
2338 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2339 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2340 pcm_close(pcm_device->pcm);
2341 pcm_device->pcm = NULL;
2342 ret = -EIO;
2343 goto error_open;
2344 }
2345 }
2346
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002347skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002348 /* force read and proc buffer reallocation in case of frame size or
2349 * channel count change */
2350 in->proc_buf_frames = 0;
2351 in->proc_buf_size = 0;
2352 in->read_buf_size = 0;
2353 in->read_buf_frames = 0;
2354
2355 /* if no supported sample rate is available, use the resampler */
2356 if (in->resampler) {
2357 in->resampler->reset(in->resampler);
2358 }
2359
2360 ALOGV("%s: exit", __func__);
2361 return ret;
2362
2363error_open:
2364 if (in->resampler) {
2365 release_resampler(in->resampler);
2366 in->resampler = NULL;
2367 }
2368 stop_input_stream(in);
2369
2370error_config:
2371 ALOGV("%s: exit: status(%d)", __func__, ret);
2372 adev->active_input = NULL;
2373 return ret;
2374}
2375
2376void lock_input_stream(struct stream_in *in)
2377{
2378 pthread_mutex_lock(&in->pre_lock);
2379 pthread_mutex_lock(&in->lock);
2380 pthread_mutex_unlock(&in->pre_lock);
2381}
2382
2383void lock_output_stream(struct stream_out *out)
2384{
2385 pthread_mutex_lock(&out->pre_lock);
2386 pthread_mutex_lock(&out->lock);
2387 pthread_mutex_unlock(&out->pre_lock);
2388}
2389
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002390static int uc_release_pcm_devices(struct audio_usecase *usecase)
2391{
2392 struct stream_out *out = (struct stream_out *)usecase->stream;
2393 struct pcm_device *pcm_device;
2394 struct listnode *node;
2395 struct listnode *next;
2396
2397 list_for_each_safe(node, next, &out->pcm_dev_list) {
2398 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2399 list_remove(node);
2400 free(pcm_device);
2401 }
2402 list_init(&usecase->mixer_list);
2403
2404 return 0;
2405}
2406
2407static int uc_select_pcm_devices(struct audio_usecase *usecase)
2408
2409{
2410 struct stream_out *out = (struct stream_out *)usecase->stream;
2411 struct pcm_device *pcm_device;
2412 struct pcm_device_profile *pcm_profile;
2413 struct mixer_card *mixer_card;
2414 audio_devices_t devices = usecase->devices;
2415
2416 list_init(&usecase->mixer_list);
2417 list_init(&out->pcm_dev_list);
2418
2419 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2420 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002421 if (pcm_device == NULL) {
2422 return -ENOMEM;
2423 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002424 pcm_device->pcm_profile = pcm_profile;
2425 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2426 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2427 if (mixer_card == NULL) {
2428 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2429 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2430 }
2431 devices &= ~pcm_profile->devices;
2432 }
2433
2434 return 0;
2435}
2436
2437static int out_close_pcm_devices(struct stream_out *out)
2438{
2439 struct pcm_device *pcm_device;
2440 struct listnode *node;
2441 struct audio_device *adev = out->dev;
2442
2443 list_for_each(node, &out->pcm_dev_list) {
2444 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2445 if (pcm_device->sound_trigger_handle > 0) {
2446 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2447 pcm_device->sound_trigger_handle = 0;
2448 }
2449 if (pcm_device->pcm) {
2450 pcm_close(pcm_device->pcm);
2451 pcm_device->pcm = NULL;
2452 }
2453 if (pcm_device->resampler) {
2454 release_resampler(pcm_device->resampler);
2455 pcm_device->resampler = NULL;
2456 }
2457 if (pcm_device->res_buffer) {
2458 free(pcm_device->res_buffer);
2459 pcm_device->res_buffer = NULL;
2460 }
2461 }
2462
2463 return 0;
2464}
2465
2466static int out_open_pcm_devices(struct stream_out *out)
2467{
2468 struct pcm_device *pcm_device;
2469 struct listnode *node;
2470 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002471 int pcm_device_card;
2472 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002473
2474 list_for_each(node, &out->pcm_dev_list) {
2475 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002476 pcm_device_card = pcm_device->pcm_profile->card;
2477 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002478
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002479 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2480 pcm_device_id = pcm_device_deep_buffer.id;
2481
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002482 if (out->dev->voice.in_call) {
2483 ALOGV("%s: in_call, not opening PCMs", __func__);
2484 return ret;
2485 }
2486
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002487 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2488 __func__, pcm_device_card, pcm_device_id);
2489
2490 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002491 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2492
2493 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2494 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2495 pcm_device->pcm = NULL;
2496 ret = -EIO;
2497 goto error_open;
2498 }
2499 /*
2500 * If the stream rate differs from the PCM rate, we need to
2501 * create a resampler.
2502 */
2503 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2504 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2505 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002506 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002507 out->sample_rate, pcm_device->pcm_profile->config.rate);
2508 ret = create_resampler(out->sample_rate,
2509 pcm_device->pcm_profile->config.rate,
2510 audio_channel_count_from_out_mask(out->channel_mask),
2511 RESAMPLER_QUALITY_DEFAULT,
2512 NULL,
2513 &pcm_device->resampler);
2514 pcm_device->res_byte_count = 0;
2515 pcm_device->res_buffer = NULL;
2516 }
2517 }
2518 return ret;
2519
2520error_open:
2521 out_close_pcm_devices(out);
2522 return ret;
2523}
2524
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002525int disable_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 = get_usecase_from_id(adev, out->usecase);
2531 if (uc_info == NULL) {
2532 ALOGE("%s: Could not find the usecase (%d) in the list",
2533 __func__, out->usecase);
2534 return -EINVAL;
2535 }
2536 disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
2537 uc_release_pcm_devices(uc_info);
2538 list_remove(&uc_info->adev_list_node);
2539 free(uc_info);
2540
2541 return 0;
2542}
2543
Andreas Schneider56204f62017-01-31 08:17:32 +01002544int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002545{
2546 struct audio_device *adev = out->dev;
2547 struct audio_usecase *uc_info;
2548
2549 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002550 if (uc_info == NULL) {
2551 return -ENOMEM;
2552 }
2553
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002554 uc_info->id = out->usecase;
2555 uc_info->type = PCM_PLAYBACK;
2556 uc_info->stream = (struct audio_stream *)out;
2557 uc_info->devices = out->devices;
2558 uc_info->in_snd_device = SND_DEVICE_NONE;
2559 uc_info->out_snd_device = SND_DEVICE_NONE;
2560 uc_select_pcm_devices(uc_info);
2561
2562 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2563 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002564
2565 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002566}
2567
2568static int stop_output_stream(struct stream_out *out)
2569{
2570 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002571 bool do_disable = true;
2572
2573 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2574 out->usecase, use_case_table[out->usecase]);
2575
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002576 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002577
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002578 if (do_disable)
2579 ret = disable_output_path_l(out);
2580
2581 ALOGV("%s: exit: status(%d)", __func__, ret);
2582 return ret;
2583}
2584
2585static int start_output_stream(struct stream_out *out)
2586{
2587 int ret = 0;
2588 struct audio_device *adev = out->dev;
2589
2590 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2591 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2592
Andreas Schneider56204f62017-01-31 08:17:32 +01002593 ret = enable_output_path_l(out);
2594 if (ret != 0) {
2595 goto error_config;
2596 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002597
2598 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2599 out->compr = NULL;
2600 ret = out_open_pcm_devices(out);
2601 if (ret != 0)
2602 goto error_open;
2603#ifdef PREPROCESSING_ENABLED
2604 out->echo_reference = NULL;
2605 out->echo_reference_generation = adev->echo_reference_generation;
2606 if (adev->echo_reference != NULL)
2607 out->echo_reference = adev->echo_reference;
2608#endif
2609 } else {
2610 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2611 COMPRESS_IN, &out->compr_config);
2612 if (out->compr && !is_compress_ready(out->compr)) {
2613 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2614 compress_close(out->compr);
2615 out->compr = NULL;
2616 ret = -EIO;
2617 goto error_open;
2618 }
2619 if (out->offload_callback)
2620 compress_nonblock(out->compr, out->non_blocking);
2621
2622 if (adev->offload_fx_start_output != NULL)
2623 adev->offload_fx_start_output(out->handle);
2624 }
2625 ALOGV("%s: exit", __func__);
2626 return 0;
2627error_open:
2628 stop_output_stream(out);
2629error_config:
2630 return ret;
2631}
2632
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002633int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002634{
2635 struct audio_usecase *uc_info;
2636
2637 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002638 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002639
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002640 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002641
2642 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2643 if (uc_info == NULL) {
2644 ALOGE("%s: Could not find the usecase (%d) in the list",
2645 __func__, USECASE_VOICE_CALL);
2646 return -EINVAL;
2647 }
2648
2649 disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
2650 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2651
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002652 list_remove(&uc_info->adev_list_node);
2653 free(uc_info);
2654
2655 ALOGV("%s: exit", __func__);
2656 return 0;
2657}
2658
2659/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002660int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002661{
2662 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002663 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002664
2665 ALOGV("%s: enter", __func__);
2666
2667 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002668 if (uc_info == NULL) {
2669 ret = -ENOMEM;
2670 goto exit;
2671 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002672 /*
2673 * We set this early so that functions called after this is being set
2674 * can use it. It is e.g. needed in select_devices() to inform the RILD
2675 * which output device we use.
2676 */
2677 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002678
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002679 uc_info->id = USECASE_VOICE_CALL;
2680 uc_info->type = VOICE_CALL;
2681 uc_info->stream = (struct audio_stream *)adev->primary_output;
2682 uc_info->devices = adev->primary_output->devices;
2683 uc_info->in_snd_device = SND_DEVICE_NONE;
2684 uc_info->out_snd_device = SND_DEVICE_NONE;
2685
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002686 list_init(&uc_info->mixer_list);
2687 list_add_tail(&uc_info->mixer_list,
2688 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002689
2690 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2691
2692 select_devices(adev, USECASE_VOICE_CALL);
2693
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002694 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002695
2696 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002697 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002698
Andreas Schneider56204f62017-01-31 08:17:32 +01002699exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002700 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002701 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002702}
2703
2704static int check_input_parameters(uint32_t sample_rate,
2705 audio_format_t format,
2706 int channel_count)
2707{
2708 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2709
2710 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2711
2712 switch (sample_rate) {
2713 case 8000:
2714 case 11025:
2715 case 12000:
2716 case 16000:
2717 case 22050:
2718 case 24000:
2719 case 32000:
2720 case 44100:
2721 case 48000:
2722 break;
2723 default:
2724 return -EINVAL;
2725 }
2726
2727 return 0;
2728}
2729
2730static size_t get_input_buffer_size(uint32_t sample_rate,
2731 audio_format_t format,
2732 int channel_count,
2733 usecase_type_t usecase_type,
2734 audio_devices_t devices)
2735{
2736 size_t size = 0;
2737 struct pcm_device_profile *pcm_profile;
2738
2739 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2740 return 0;
2741
2742 pcm_profile = get_pcm_device(usecase_type, devices);
2743 if (pcm_profile == NULL)
2744 return 0;
2745
2746 /*
2747 * take resampling into account and return the closest majoring
2748 * multiple of 16 frames, as audioflinger expects audio buffers to
2749 * be a multiple of 16 frames
2750 */
2751 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2752 size = ((size + 15) / 16) * 16;
2753
2754 return (size * channel_count * audio_bytes_per_sample(format));
2755
2756}
2757
2758static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2759{
2760 struct stream_out *out = (struct stream_out *)stream;
2761
2762 return out->sample_rate;
2763}
2764
2765static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2766{
2767 (void)stream;
2768 (void)rate;
2769 return -ENOSYS;
2770}
2771
2772static size_t out_get_buffer_size(const struct audio_stream *stream)
2773{
2774 struct stream_out *out = (struct stream_out *)stream;
2775
2776 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2777 return out->compr_config.fragment_size;
2778 }
2779
2780 return out->config.period_size *
2781 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2782}
2783
2784static uint32_t out_get_channels(const struct audio_stream *stream)
2785{
2786 struct stream_out *out = (struct stream_out *)stream;
2787
2788 return out->channel_mask;
2789}
2790
2791static audio_format_t out_get_format(const struct audio_stream *stream)
2792{
2793 struct stream_out *out = (struct stream_out *)stream;
2794
2795 return out->format;
2796}
2797
2798static int out_set_format(struct audio_stream *stream, audio_format_t format)
2799{
2800 (void)stream;
2801 (void)format;
2802 return -ENOSYS;
2803}
2804
2805static int do_out_standby_l(struct stream_out *out)
2806{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002807 int status = 0;
2808
2809 out->standby = true;
2810 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2811 out_close_pcm_devices(out);
2812#ifdef PREPROCESSING_ENABLED
2813 /* stop writing to echo reference */
2814 if (out->echo_reference != NULL) {
2815 out->echo_reference->write(out->echo_reference, NULL);
2816 if (out->echo_reference_generation != adev->echo_reference_generation) {
2817 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2818 release_echo_reference(out->echo_reference);
2819 out->echo_reference_generation = adev->echo_reference_generation;
2820 }
2821 out->echo_reference = NULL;
2822 }
2823#endif
2824 } else {
2825 stop_compressed_output_l(out);
2826 out->gapless_mdata.encoder_delay = 0;
2827 out->gapless_mdata.encoder_padding = 0;
2828 if (out->compr != NULL) {
2829 compress_close(out->compr);
2830 out->compr = NULL;
2831 }
2832 }
2833 status = stop_output_stream(out);
2834
2835 return status;
2836}
2837
2838static int out_standby(struct audio_stream *stream)
2839{
2840 struct stream_out *out = (struct stream_out *)stream;
2841 struct audio_device *adev = out->dev;
2842
2843 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2844 out->usecase, use_case_table[out->usecase]);
2845 lock_output_stream(out);
2846 if (!out->standby) {
2847 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002848 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002849 do_out_standby_l(out);
2850 pthread_mutex_unlock(&adev->lock);
2851 }
2852 pthread_mutex_unlock(&out->lock);
2853 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002854
2855 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2856
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002857 return 0;
2858}
2859
2860static int out_dump(const struct audio_stream *stream, int fd)
2861{
2862 (void)stream;
2863 (void)fd;
2864
2865 return 0;
2866}
2867
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002868static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2869{
2870 struct stream_out *out = (struct stream_out *)stream;
2871 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002872 struct listnode *node;
2873 struct str_parms *parms;
2874 char value[32];
2875 int ret, val = 0;
2876 struct audio_usecase *uc_info;
2877 bool do_standby = false;
2878 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002879#ifdef PREPROCESSING_ENABLED
2880 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2881#endif
2882
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002883 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2884 "adev->mode(%#x)",
2885 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2886 out->devices, adev->mode);
2887
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002888 parms = str_parms_create_str(kvpairs);
2889 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2890 if (ret >= 0) {
2891 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002892
2893 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2894 __func__, out->usecase, use_case_table[out->usecase], val,
2895 adev->mode);
2896
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002897 pthread_mutex_lock(&adev->lock_inputs);
2898 lock_output_stream(out);
2899 pthread_mutex_lock(&adev->lock);
2900#ifdef PREPROCESSING_ENABLED
2901 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2902 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2903 /* reset active input:
2904 * - to attach the echo reference
2905 * - because a change in output device may change mic settings */
2906 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2907 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2908 in = adev->active_input;
2909 }
2910 }
2911#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002912 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002913 bool bt_sco_active = false;
2914
2915 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2916 bt_sco_active = true;
2917 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002918 out->devices = val;
2919
2920 if (!out->standby) {
2921 uc_info = get_usecase_from_id(adev, out->usecase);
2922 if (uc_info == NULL) {
2923 ALOGE("%s: Could not find the usecase (%d) in the list",
2924 __func__, out->usecase);
2925 } else {
2926 list_for_each(node, &out->pcm_dev_list) {
2927 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2928 if ((pcm_device->pcm_profile->devices & val) == 0)
2929 do_standby = true;
2930 val &= ~pcm_device->pcm_profile->devices;
2931 }
2932 if (val != 0)
2933 do_standby = true;
2934 }
2935 if (do_standby)
2936 do_out_standby_l(out);
2937 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002938 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2939 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002940 select_devices(adev, out->usecase);
2941 }
2942 }
2943
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002944 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002945 (out == adev->primary_output)) {
2946 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002947 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2948 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002949 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002950 /* Turn on bluetooth if needed */
2951 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002952 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002953 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002954 } else {
2955 /*
2956 * When we select different devices we need to restart the
2957 * voice call. The modem closes the stream on its end and
2958 * we do not get any output.
2959 */
2960 stop_voice_call(adev);
2961 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002962 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002963 }
2964 }
2965
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002966 pthread_mutex_unlock(&adev->lock);
2967 pthread_mutex_unlock(&out->lock);
2968#ifdef PREPROCESSING_ENABLED
2969 if (in) {
2970 /* The lock on adev->lock_inputs prevents input stream from being closed */
2971 lock_input_stream(in);
2972 pthread_mutex_lock(&adev->lock);
2973 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2974 do_in_standby_l(in);
2975 pthread_mutex_unlock(&adev->lock);
2976 pthread_mutex_unlock(&in->lock);
2977 }
2978#endif
2979 pthread_mutex_unlock(&adev->lock_inputs);
2980 }
2981
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002982 amplifier_set_parameters(parms);
2983
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002984 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2985 parse_compress_metadata(out, parms);
2986 }
2987
2988 str_parms_destroy(parms);
2989
2990 if (ret > 0)
2991 ret = 0;
2992 ALOGV("%s: exit: code(%d)", __func__, ret);
2993 return ret;
2994}
2995
2996static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2997{
2998 struct stream_out *out = (struct stream_out *)stream;
2999 struct str_parms *query = str_parms_create_str(keys);
3000 char *str;
3001 char value[256];
3002 struct str_parms *reply = str_parms_create();
3003 size_t i, j;
3004 int ret;
3005 bool first = true;
3006 ALOGV("%s: enter: keys - %s", __func__, keys);
3007 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
3008 if (ret >= 0) {
3009 value[0] = '\0';
3010 i = 0;
3011 while (out->supported_channel_masks[i] != 0) {
3012 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
3013 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
3014 if (!first) {
3015 strcat(value, "|");
3016 }
3017 strcat(value, out_channels_name_to_enum_table[j].name);
3018 first = false;
3019 break;
3020 }
3021 }
3022 i++;
3023 }
3024 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
3025 str = str_parms_to_str(reply);
3026 } else {
3027 str = strdup(keys);
3028 }
3029 str_parms_destroy(query);
3030 str_parms_destroy(reply);
3031 ALOGV("%s: exit: returns - %s", __func__, str);
3032 return str;
3033}
3034
3035static uint32_t out_get_latency(const struct audio_stream_out *stream)
3036{
3037 struct stream_out *out = (struct stream_out *)stream;
3038
3039 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3040 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
3041
3042 return (out->config.period_count * out->config.period_size * 1000) /
3043 (out->config.rate);
3044}
3045
3046static int out_set_volume(struct audio_stream_out *stream, float left,
3047 float right)
3048{
3049 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003050
3051 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
3052 /* only take left channel into account: the API is for stereo anyway */
3053 out->muted = (left == 0.0f);
3054 return 0;
3055 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003056 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003057 }
3058
3059 return -ENOSYS;
3060}
3061
Andreas Schneider3b643832017-01-31 11:48:22 +01003062#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003063static int fast_set_affinity(pid_t tid) {
3064 cpu_set_t cpu_set;
3065 int cpu_num;
3066 const char *irq_procfs = "/proc/asound/irq_affinity";
3067 FILE *fp;
3068
3069 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3070 ALOGW("Procfs node %s not found", irq_procfs);
3071 return -1;
3072 }
3073
3074 if (fscanf(fp, "%d", &cpu_num) != 1) {
3075 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3076 fclose(fp);
3077 return -1;
3078 }
3079 fclose(fp);
3080
3081 CPU_ZERO(&cpu_set);
3082 CPU_SET(cpu_num, &cpu_set);
3083 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3084}
Andreas Schneider3b643832017-01-31 11:48:22 +01003085#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003086
3087static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3088 size_t bytes)
3089{
3090 struct stream_out *out = (struct stream_out *)stream;
3091 struct audio_device *adev = out->dev;
3092 ssize_t ret = 0;
3093 struct pcm_device *pcm_device;
3094 struct listnode *node;
3095 size_t frame_size = audio_stream_out_frame_size(stream);
3096 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003097#ifdef PREPROCESSING_ENABLED
3098 size_t in_frames = bytes / frame_size;
3099 size_t out_frames = in_frames;
3100 struct stream_in *in = NULL;
3101#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003102
3103 lock_output_stream(out);
3104
Andreas Schneider3b643832017-01-31 11:48:22 +01003105#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003106 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003107 pid_t tid = gettid();
3108 int err;
3109
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003110 err = fast_set_affinity(tid);
3111 if (err < 0) {
3112 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3113 }
3114 out->is_fastmixer_affinity_set = true;
3115 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003116#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003117
3118 if (out->standby) {
3119#ifdef PREPROCESSING_ENABLED
3120 pthread_mutex_unlock(&out->lock);
3121 /* Prevent input stream from being closed */
3122 pthread_mutex_lock(&adev->lock_inputs);
3123 lock_output_stream(out);
3124 if (!out->standby) {
3125 pthread_mutex_unlock(&adev->lock_inputs);
3126 goto false_alarm;
3127 }
3128#endif
3129 pthread_mutex_lock(&adev->lock);
3130 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003131 if (ret == 0) {
3132 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3133 }
3134
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003135 /* ToDo: If use case is compress offload should return 0 */
3136 if (ret != 0) {
3137 pthread_mutex_unlock(&adev->lock);
3138#ifdef PREPROCESSING_ENABLED
3139 pthread_mutex_unlock(&adev->lock_inputs);
3140#endif
3141 goto exit;
3142 }
3143 out->standby = false;
3144
3145#ifdef PREPROCESSING_ENABLED
3146 /* A change in output device may change the microphone selection */
3147 if (adev->active_input &&
3148 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3149 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3150 in = adev->active_input;
3151 ALOGV("%s: enter:) force_input_standby true", __func__);
3152 }
3153#endif
3154 pthread_mutex_unlock(&adev->lock);
3155#ifdef PREPROCESSING_ENABLED
3156 if (!in) {
3157 /* Leave mutex locked iff in != NULL */
3158 pthread_mutex_unlock(&adev->lock_inputs);
3159 }
3160#endif
3161 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003162#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003163false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003164#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003165
3166 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003167 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003168 return ret;
3169 } else {
3170#ifdef PREPROCESSING_ENABLED
3171 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3172 != out->echo_reference_generation) {
3173 pthread_mutex_lock(&adev->lock);
3174 if (out->echo_reference != NULL) {
3175 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3176 release_echo_reference(out->echo_reference);
3177 }
3178 // note that adev->echo_reference_generation here can be different from the one
3179 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3180 // with what has been set by get_echo_reference() or put_echo_reference()
3181 out->echo_reference_generation = adev->echo_reference_generation;
3182 out->echo_reference = adev->echo_reference;
3183 ALOGV("%s: update echo reference generation %d", __func__,
3184 out->echo_reference_generation);
3185 pthread_mutex_unlock(&adev->lock);
3186 }
3187#endif
3188
3189 if (out->muted)
3190 memset((void *)buffer, 0, bytes);
3191 list_for_each(node, &out->pcm_dev_list) {
3192 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3193 if (pcm_device->resampler) {
3194 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3195 > pcm_device->res_byte_count) {
3196 pcm_device->res_byte_count =
3197 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3198 pcm_device->res_buffer =
3199 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3200 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3201 pcm_device->res_byte_count);
3202 }
3203 frames_rq = bytes / frame_size;
3204 frames_wr = pcm_device->res_byte_count / frame_size;
3205 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3206 __func__, frames_rq, frame_size);
3207 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3208 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3209 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3210 }
3211 if (pcm_device->pcm) {
3212#ifdef PREPROCESSING_ENABLED
3213 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3214 struct echo_reference_buffer b;
3215 b.raw = (void *)buffer;
3216 b.frame_count = in_frames;
3217
3218 get_playback_delay(out, out_frames, &b);
3219 out->echo_reference->write(out->echo_reference, &b);
3220 }
3221#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003222 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3223 if (pcm_device->resampler && pcm_device->res_buffer)
3224 pcm_device->status =
3225 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3226 frames_wr * frame_size);
3227 else
3228 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3229 if (pcm_device->status != 0)
3230 ret = pcm_device->status;
3231 }
3232 }
3233 if (ret == 0)
3234 out->written += bytes / (out->config.channels * sizeof(short));
3235 }
3236
3237exit:
3238 pthread_mutex_unlock(&out->lock);
3239
3240 if (ret != 0) {
3241 list_for_each(node, &out->pcm_dev_list) {
3242 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3243 if (pcm_device->pcm && pcm_device->status != 0)
3244 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3245 }
3246 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003247 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3248 clock_gettime(CLOCK_MONOTONIC, &t);
3249 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3250 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3251 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3252 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3253 if (sleep_time > 0) {
3254 usleep(sleep_time);
3255 } else {
3256 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3257 sleep_time = 0;
3258 }
3259 out->last_write_time_us = now + sleep_time;
3260 // last_write_time_us is an approximation of when the (simulated) alsa
3261 // buffer is believed completely full. The usleep above waits for more space
3262 // in the buffer, but by the end of the sleep the buffer is considered
3263 // topped-off.
3264 //
3265 // On the subsequent out_write(), we measure the elapsed time spent in
3266 // the mixer. This is subtracted from the sleep estimate based on frames,
3267 // thereby accounting for drain in the alsa buffer during mixing.
3268 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003269 }
3270
3271#ifdef PREPROCESSING_ENABLED
3272 if (in) {
3273 /* The lock on adev->lock_inputs prevents input stream from being closed */
3274 lock_input_stream(in);
3275 pthread_mutex_lock(&adev->lock);
3276 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3277 do_in_standby_l(in);
3278 pthread_mutex_unlock(&adev->lock);
3279 pthread_mutex_unlock(&in->lock);
3280 /* This mutex was left locked iff in != NULL */
3281 pthread_mutex_unlock(&adev->lock_inputs);
3282 }
3283#endif
3284
3285 return bytes;
3286}
3287
3288static int out_get_render_position(const struct audio_stream_out *stream,
3289 uint32_t *dsp_frames)
3290{
3291 struct stream_out *out = (struct stream_out *)stream;
3292 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003293 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3294 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003295 } else
3296 return -EINVAL;
3297}
3298
3299static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3300{
3301 (void)stream;
3302 (void)effect;
3303 return 0;
3304}
3305
3306static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3307{
3308 (void)stream;
3309 (void)effect;
3310 return 0;
3311}
3312
3313static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3314 int64_t *timestamp)
3315{
3316 (void)stream;
3317 (void)timestamp;
3318 return -EINVAL;
3319}
3320
3321static int out_get_presentation_position(const struct audio_stream_out *stream,
3322 uint64_t *frames, struct timespec *timestamp)
3323{
3324 struct stream_out *out = (struct stream_out *)stream;
3325 int ret = -1;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003326
3327 lock_output_stream(out);
3328
3329 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003330 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003331 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003332 if (out->dev->voice.in_call) {
3333 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3334 ret = 0;
3335 goto done;
3336 }
3337
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003338 /* FIXME: which device to read from? */
3339 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003340 struct pcm_device *pcm_device;
3341 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003342 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003343
Andreas Schneiderd6359182017-02-08 16:58:22 +01003344 list_for_each(node, &out->pcm_dev_list) {
3345 pcm_device = node_to_item(node,
3346 struct pcm_device,
3347 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003348
Andreas Schneiderd6359182017-02-08 16:58:22 +01003349 if (pcm_device->pcm != NULL) {
3350 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3351 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3352 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3353 /* This adjustment accounts for buffering after app processor.
3354 It is based on estimated DSP latency per use case, rather than exact. */
3355 signed_frames -=
3356 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3357
3358 /* It would be unusual for this value to be negative, but check just in case ... */
3359 if (signed_frames >= 0) {
3360 *frames = signed_frames;
3361 ret = 0;
3362 goto done;
3363 }
3364 ret = -1;
3365 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003366 }
3367 }
3368 }
3369 }
3370
Andreas Schneiderd6359182017-02-08 16:58:22 +01003371done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003372 pthread_mutex_unlock(&out->lock);
3373
3374 return ret;
3375}
3376
3377static int out_set_callback(struct audio_stream_out *stream,
3378 stream_callback_t callback, void *cookie)
3379{
3380 struct stream_out *out = (struct stream_out *)stream;
3381
3382 ALOGV("%s", __func__);
3383 lock_output_stream(out);
3384 out->offload_callback = callback;
3385 out->offload_cookie = cookie;
3386 pthread_mutex_unlock(&out->lock);
3387 return 0;
3388}
3389
3390static int out_pause(struct audio_stream_out* stream)
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_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003397 return status;
3398}
3399
3400static int out_resume(struct audio_stream_out* stream)
3401{
3402 struct stream_out *out = (struct stream_out *)stream;
3403 int status = -ENOSYS;
3404 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003405 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3406 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003407 return status;
3408}
3409
3410static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3411{
3412 struct stream_out *out = (struct stream_out *)stream;
3413 int status = -ENOSYS;
3414 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003415 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3416 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003417 return status;
3418}
3419
3420static int out_flush(struct audio_stream_out* stream)
3421{
3422 struct stream_out *out = (struct stream_out *)stream;
3423 ALOGV("%s", __func__);
3424 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003425 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003426 }
3427 return -ENOSYS;
3428}
3429
3430/** audio_stream_in implementation **/
3431static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3432{
3433 struct stream_in *in = (struct stream_in *)stream;
3434
3435 return in->requested_rate;
3436}
3437
3438static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3439{
3440 (void)stream;
3441 (void)rate;
3442 return -ENOSYS;
3443}
3444
3445static uint32_t in_get_channels(const struct audio_stream *stream)
3446{
3447 struct stream_in *in = (struct stream_in *)stream;
3448
3449 return in->main_channels;
3450}
3451
3452static audio_format_t in_get_format(const struct audio_stream *stream)
3453{
3454 (void)stream;
3455 return AUDIO_FORMAT_PCM_16_BIT;
3456}
3457
3458static int in_set_format(struct audio_stream *stream, audio_format_t format)
3459{
3460 (void)stream;
3461 (void)format;
3462
3463 return -ENOSYS;
3464}
3465
3466static size_t in_get_buffer_size(const struct audio_stream *stream)
3467{
3468 struct stream_in *in = (struct stream_in *)stream;
3469
3470 return get_input_buffer_size(in->requested_rate,
3471 in_get_format(stream),
3472 audio_channel_count_from_in_mask(in->main_channels),
3473 in->usecase_type,
3474 in->devices);
3475}
3476
3477static int in_close_pcm_devices(struct stream_in *in)
3478{
3479 struct pcm_device *pcm_device;
3480 struct listnode *node;
3481 struct audio_device *adev = in->dev;
3482
3483 list_for_each(node, &in->pcm_dev_list) {
3484 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3485 if (pcm_device) {
3486 if (pcm_device->pcm)
3487 pcm_close(pcm_device->pcm);
3488 pcm_device->pcm = NULL;
3489 if (pcm_device->sound_trigger_handle > 0)
3490 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3491 pcm_device->sound_trigger_handle = 0;
3492 }
3493 }
3494 return 0;
3495}
3496
3497
3498/* must be called with stream and hw device mutex locked */
3499static int do_in_standby_l(struct stream_in *in)
3500{
3501 int status = 0;
3502
3503#ifdef PREPROCESSING_ENABLED
3504 struct audio_device *adev = in->dev;
3505#endif
3506 if (!in->standby) {
3507
3508 in_close_pcm_devices(in);
3509
3510#ifdef PREPROCESSING_ENABLED
3511 if (in->echo_reference != NULL) {
3512 /* stop reading from echo reference */
3513 in->echo_reference->read(in->echo_reference, NULL);
3514 put_echo_reference(adev, in->echo_reference);
3515 in->echo_reference = NULL;
3516 }
3517#ifdef HW_AEC_LOOPBACK
3518 if (in->hw_echo_reference)
3519 {
3520 if (in->hw_ref_buf) {
3521 free(in->hw_ref_buf);
3522 in->hw_ref_buf = NULL;
3523 }
3524 }
3525#endif // HW_AEC_LOOPBACK
3526#endif // PREPROCESSING_ENABLED
3527
3528 status = stop_input_stream(in);
3529
3530 if (in->read_buf) {
3531 free(in->read_buf);
3532 in->read_buf = NULL;
3533 }
3534
3535 in->standby = 1;
3536 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003537
3538 in->last_read_time_us = 0;
3539
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003540 return 0;
3541}
3542
3543// called with adev->lock_inputs locked
3544static int in_standby_l(struct stream_in *in)
3545{
3546 struct audio_device *adev = in->dev;
3547 int status = 0;
3548 lock_input_stream(in);
3549 if (!in->standby) {
3550 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003551 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003552 status = do_in_standby_l(in);
3553 pthread_mutex_unlock(&adev->lock);
3554 }
3555 pthread_mutex_unlock(&in->lock);
3556 return status;
3557}
3558
3559static int in_standby(struct audio_stream *stream)
3560{
3561 struct stream_in *in = (struct stream_in *)stream;
3562 struct audio_device *adev = in->dev;
3563 int status;
3564 ALOGV("%s: enter", __func__);
3565 pthread_mutex_lock(&adev->lock_inputs);
3566 status = in_standby_l(in);
3567 pthread_mutex_unlock(&adev->lock_inputs);
3568 ALOGV("%s: exit: status(%d)", __func__, status);
3569 return status;
3570}
3571
3572static int in_dump(const struct audio_stream *stream, int fd)
3573{
3574 (void)stream;
3575 (void)fd;
3576
3577 return 0;
3578}
3579
3580static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3581{
3582 struct stream_in *in = (struct stream_in *)stream;
3583 struct audio_device *adev = in->dev;
3584 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003585 char value[32];
3586 int ret, val = 0;
3587 struct audio_usecase *uc_info;
3588 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003589 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003590
3591 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3592 parms = str_parms_create_str(kvpairs);
3593
3594 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3595
3596 pthread_mutex_lock(&adev->lock_inputs);
3597 lock_input_stream(in);
3598 pthread_mutex_lock(&adev->lock);
3599 if (ret >= 0) {
3600 val = atoi(value);
3601 /* no audio source uses val == 0 */
3602 if (((int)in->source != val) && (val != 0)) {
3603 in->source = val;
3604 }
3605 }
3606
3607 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3608 if (ret >= 0) {
3609 val = atoi(value);
3610 if (((int)in->devices != val) && (val != 0)) {
3611 in->devices = val;
3612 /* If recording is in progress, change the tx device to new device */
3613 if (!in->standby) {
3614 uc_info = get_usecase_from_id(adev, in->usecase);
3615 if (uc_info == NULL) {
3616 ALOGE("%s: Could not find the usecase (%d) in the list",
3617 __func__, in->usecase);
3618 } else {
3619 if (list_empty(&in->pcm_dev_list))
3620 ALOGE("%s: pcm device list empty", __func__);
3621 else {
3622 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3623 struct pcm_device, stream_list_node);
3624 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3625 do_standby = true;
3626 }
3627 }
3628 }
3629 if (do_standby) {
3630 ret = do_in_standby_l(in);
3631 } else
3632 ret = select_devices(adev, in->usecase);
3633 }
3634 }
3635 }
3636 pthread_mutex_unlock(&adev->lock);
3637 pthread_mutex_unlock(&in->lock);
3638 pthread_mutex_unlock(&adev->lock_inputs);
3639 str_parms_destroy(parms);
3640
3641 if (ret > 0)
3642 ret = 0;
3643
3644 ALOGV("%s: exit: status(%d)", __func__, ret);
3645 return ret;
3646}
3647
3648static char* in_get_parameters(const struct audio_stream *stream,
3649 const char *keys)
3650{
3651 (void)stream;
3652 (void)keys;
3653
3654 return strdup("");
3655}
3656
3657static int in_set_gain(struct audio_stream_in *stream, float gain)
3658{
3659 (void)stream;
3660 (void)gain;
3661
3662 return 0;
3663}
3664
3665static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3666 size_t bytes)
3667{
3668 struct pcm_device *pcm_device;
3669 struct audio_device *adev = in->dev;
3670
3671 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3672 struct pcm_device, stream_list_node);
3673
3674 if (pcm_device->sound_trigger_handle > 0)
3675 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3676 else
3677 return 0;
3678}
3679
3680static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3681 size_t bytes)
3682{
3683 struct stream_in *in = (struct stream_in *)stream;
3684 struct audio_device *adev = in->dev;
3685 ssize_t frames = -1;
3686 int ret = -1;
3687 int read_and_process_successful = false;
3688
3689 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003690
3691 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3692 lock_input_stream(in);
3693
Andreas Schneider3b643832017-01-31 11:48:22 +01003694#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003695 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003696 pid_t tid = gettid();
3697 int err;
3698
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003699 err = fast_set_affinity(tid);
3700 if (err < 0) {
3701 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3702 }
3703 in->is_fastcapture_affinity_set = true;
3704 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003705#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003706
3707 if (in->standby) {
3708 pthread_mutex_unlock(&in->lock);
3709 pthread_mutex_lock(&adev->lock_inputs);
3710 lock_input_stream(in);
3711 if (!in->standby) {
3712 pthread_mutex_unlock(&adev->lock_inputs);
3713 goto false_alarm;
3714 }
3715 pthread_mutex_lock(&adev->lock);
3716 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003717 if (ret == 0) {
3718 amplifier_input_stream_start(stream);
3719 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003720 pthread_mutex_unlock(&adev->lock);
3721 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003722
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003723 if (ret != 0) {
3724 goto exit;
3725 }
3726 in->standby = 0;
3727 }
3728false_alarm:
3729
3730 if (!list_empty(&in->pcm_dev_list)) {
3731 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3732 bytes = read_bytes_from_dsp(in, buffer, bytes);
3733 if (bytes > 0)
3734 read_and_process_successful = true;
3735 } else {
3736 /*
3737 * Read PCM and:
3738 * - resample if needed
3739 * - process if pre-processors are attached
3740 * - discard unwanted channels
3741 */
3742 frames = read_and_process_frames(in, buffer, frames_rq);
3743 if (frames >= 0)
3744 read_and_process_successful = true;
3745 }
3746 }
3747
3748 /*
3749 * Instead of writing zeroes here, we could trust the hardware
3750 * to always provide zeroes when muted.
3751 */
3752 if (read_and_process_successful == true && adev->mic_mute)
3753 memset(buffer, 0, bytes);
3754
3755exit:
3756 pthread_mutex_unlock(&in->lock);
3757
3758 if (read_and_process_successful == false) {
3759 in_standby(&in->stream.common);
3760 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003761 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3762 clock_gettime(CLOCK_MONOTONIC, &t);
3763 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3764
3765 // we do a full sleep when exiting standby.
3766 const bool standby = in->last_read_time_us == 0;
3767 const int64_t elapsed_time_since_last_read = standby ?
3768 0 : now - in->last_read_time_us;
3769 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3770 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3771 if (sleep_time > 0) {
3772 usleep(sleep_time);
3773 } else {
3774 sleep_time = 0;
3775 }
3776 in->last_read_time_us = now + sleep_time;
3777 // last_read_time_us is an approximation of when the (simulated) alsa
3778 // buffer is drained by the read, and is empty.
3779 //
3780 // On the subsequent in_read(), we measure the elapsed time spent in
3781 // the recording thread. This is subtracted from the sleep estimate based on frames,
3782 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003783 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003784 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003785
3786 if (bytes > 0) {
3787 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3788 }
3789
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003790 return bytes;
3791}
3792
3793static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3794{
3795 (void)stream;
3796
3797 return 0;
3798}
3799
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003800static int in_get_capture_position(const struct audio_stream_in *stream,
3801 int64_t *frames, int64_t *time)
3802{
3803 if (stream == NULL || frames == NULL || time == NULL) {
3804 return -EINVAL;
3805 }
3806
3807 struct stream_in *in = (struct stream_in *)stream;
3808 struct pcm_device *pcm_device;
3809 int ret = -ENOSYS;
3810
3811 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3812 struct pcm_device, stream_list_node);
3813
3814 pthread_mutex_lock(&in->lock);
3815 if (pcm_device->pcm) {
3816 struct timespec timestamp;
3817 unsigned int avail;
3818 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3819 *frames = in->frames_read + avail;
3820 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3821 ret = 0;
3822 }
3823 }
3824
3825 pthread_mutex_unlock(&in->lock);
3826 return ret;
3827}
3828
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003829static int add_remove_audio_effect(const struct audio_stream *stream,
3830 effect_handle_t effect,
3831 bool enable)
3832{
3833 struct stream_in *in = (struct stream_in *)stream;
3834 struct audio_device *adev = in->dev;
3835 int status = 0;
3836 effect_descriptor_t desc;
3837#ifdef PREPROCESSING_ENABLED
3838 int i;
3839#endif
3840 status = (*effect)->get_descriptor(effect, &desc);
3841 if (status != 0)
3842 return status;
3843
3844 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3845
3846 pthread_mutex_lock(&adev->lock_inputs);
3847 lock_input_stream(in);
3848 pthread_mutex_lock(&in->dev->lock);
3849#ifndef PREPROCESSING_ENABLED
3850 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3851 in->enable_aec != enable &&
3852 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3853 in->enable_aec = enable;
3854 if (!in->standby)
3855 select_devices(in->dev, in->usecase);
3856 }
3857#else
3858 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3859 status = -ENOSYS;
3860 goto exit;
3861 }
3862 if ( enable == true ) {
3863 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3864 /* add the supported channel of the effect in the channel_configs */
3865 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3866 in->num_preprocessors ++;
3867 /* check compatibility between main channel supported and possible auxiliary channels */
3868 in_update_aux_channels(in, effect);//wesley crash
3869 in->aux_channels_changed = true;
3870 } else {
3871 /* if ( enable == false ) */
3872 if (in->num_preprocessors <= 0) {
3873 status = -ENOSYS;
3874 goto exit;
3875 }
3876 status = -EINVAL;
3877 for (i=0; i < in->num_preprocessors; i++) {
3878 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3879 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3880 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3881 in->preprocessors[i - 1].num_channel_configs =
3882 in->preprocessors[i].num_channel_configs;
3883 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3884 continue;
3885 }
3886 if ( in->preprocessors[i].effect_itfe == effect ) {
3887 ALOGV("add_remove_audio_effect found fx at index %d", i);
3888 free(in->preprocessors[i].channel_configs);
3889 status = 0;
3890 }
3891 }
3892 if (status != 0)
3893 goto exit;
3894 in->num_preprocessors--;
3895 /* if we remove one effect, at least the last proproc should be reset */
3896 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3897 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3898 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3899 in->aux_channels_changed = false;
3900 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3901 }
3902 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3903
3904 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3905 in->enable_aec = enable;
3906 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3907 if (!in->standby) {
3908 select_devices(in->dev, in->usecase);
3909 do_in_standby_l(in);
3910 }
3911 if (in->enable_aec == true) {
3912 in_configure_reverse(in);
3913 }
3914 }
3915exit:
3916#endif
3917 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3918 pthread_mutex_unlock(&in->dev->lock);
3919 pthread_mutex_unlock(&in->lock);
3920 pthread_mutex_unlock(&adev->lock_inputs);
3921 return status;
3922}
3923
3924static int in_add_audio_effect(const struct audio_stream *stream,
3925 effect_handle_t effect)
3926{
3927 ALOGV("%s: effect %p", __func__, effect);
3928 return add_remove_audio_effect(stream, effect, true);
3929}
3930
3931static int in_remove_audio_effect(const struct audio_stream *stream,
3932 effect_handle_t effect)
3933{
3934 ALOGV("%s: effect %p", __func__, effect);
3935 return add_remove_audio_effect(stream, effect, false);
3936}
3937
3938static int adev_open_output_stream(struct audio_hw_device *dev,
3939 audio_io_handle_t handle,
3940 audio_devices_t devices,
3941 audio_output_flags_t flags,
3942 struct audio_config *config,
3943 struct audio_stream_out **stream_out,
3944 const char *address __unused)
3945{
3946 struct audio_device *adev = (struct audio_device *)dev;
3947 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003948 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003949 struct pcm_device_profile *pcm_profile;
3950
3951 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3952 __func__, config->sample_rate, config->channel_mask, devices, flags);
3953 *stream_out = NULL;
3954 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003955 if (out == NULL) {
3956 ret = -ENOMEM;
3957 goto error_config;
3958 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003959
3960 if (devices == AUDIO_DEVICE_NONE)
3961 devices = AUDIO_DEVICE_OUT_SPEAKER;
3962
3963 out->flags = flags;
3964 out->devices = devices;
3965 out->dev = adev;
3966 out->format = config->format;
3967 out->sample_rate = config->sample_rate;
3968 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3969 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3970 out->handle = handle;
3971
3972 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3973 if (pcm_profile == NULL) {
3974 ret = -EINVAL;
3975 goto error_open;
3976 }
3977 out->config = pcm_profile->config;
3978
3979 /* Init use case and pcm_config */
3980 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3981 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3982 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3983 ALOGE("%s: Unsupported Offload information", __func__);
3984 ret = -EINVAL;
3985 goto error_open;
3986 }
3987 if (!is_supported_format(config->offload_info.format)) {
3988 ALOGE("%s: Unsupported audio format", __func__);
3989 ret = -EINVAL;
3990 goto error_open;
3991 }
3992
3993 out->compr_config.codec = (struct snd_codec *)
3994 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003995 if (out->compr_config.codec == NULL) {
3996 ret = -ENOMEM;
3997 goto error_open;
3998 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003999
4000 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
4001 if (config->offload_info.channel_mask)
4002 out->channel_mask = config->offload_info.channel_mask;
4003 else if (config->channel_mask)
4004 out->channel_mask = config->channel_mask;
4005 out->format = config->offload_info.format;
4006 out->sample_rate = config->offload_info.sample_rate;
4007
4008 out->stream.set_callback = out_set_callback;
4009 out->stream.pause = out_pause;
4010 out->stream.resume = out_resume;
4011 out->stream.drain = out_drain;
4012 out->stream.flush = out_flush;
4013
4014 out->compr_config.codec->id =
4015 get_snd_codec_id(config->offload_info.format);
4016 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
4017 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
4018 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
4019 out->compr_config.codec->bit_rate =
4020 config->offload_info.bit_rate;
4021 out->compr_config.codec->ch_in =
4022 audio_channel_count_from_out_mask(config->channel_mask);
4023 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4024
4025 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4026 out->non_blocking = 1;
4027
4028 out->send_new_metadata = 1;
4029 create_offload_callback_thread(out);
4030 out->offload_state = OFFLOAD_STATE_IDLE;
4031
4032 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4033 __func__, config->offload_info.version,
4034 config->offload_info.bit_rate);
4035 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4036 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004037 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004038 out->sample_rate = out->config.rate;
4039 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4040 } else {
4041 out->usecase = USECASE_AUDIO_PLAYBACK;
4042 out->sample_rate = out->config.rate;
4043 }
4044
4045 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4046 if (adev->primary_output == NULL)
4047 adev->primary_output = out;
4048 else {
4049 ALOGE("%s: Primary output is already opened", __func__);
4050 ret = -EEXIST;
4051 goto error_open;
4052 }
4053 }
4054
4055 /* Check if this usecase is already existing */
4056 pthread_mutex_lock(&adev->lock);
4057 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4058 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4059 pthread_mutex_unlock(&adev->lock);
4060 ret = -EEXIST;
4061 goto error_open;
4062 }
4063 pthread_mutex_unlock(&adev->lock);
4064
4065 out->stream.common.get_sample_rate = out_get_sample_rate;
4066 out->stream.common.set_sample_rate = out_set_sample_rate;
4067 out->stream.common.get_buffer_size = out_get_buffer_size;
4068 out->stream.common.get_channels = out_get_channels;
4069 out->stream.common.get_format = out_get_format;
4070 out->stream.common.set_format = out_set_format;
4071 out->stream.common.standby = out_standby;
4072 out->stream.common.dump = out_dump;
4073 out->stream.common.set_parameters = out_set_parameters;
4074 out->stream.common.get_parameters = out_get_parameters;
4075 out->stream.common.add_audio_effect = out_add_audio_effect;
4076 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4077 out->stream.get_latency = out_get_latency;
4078 out->stream.set_volume = out_set_volume;
4079 out->stream.write = out_write;
4080 out->stream.get_render_position = out_get_render_position;
4081 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4082 out->stream.get_presentation_position = out_get_presentation_position;
4083
4084 out->standby = 1;
4085 /* out->muted = false; by calloc() */
4086 /* out->written = 0; by calloc() */
4087
4088 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4089 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4090 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4091
4092 config->format = out->stream.common.get_format(&out->stream.common);
4093 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4094 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4095
4096 out->is_fastmixer_affinity_set = false;
4097
4098 *stream_out = &out->stream;
4099 ALOGV("%s: exit", __func__);
4100 return 0;
4101
4102error_open:
4103 free(out);
4104 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004105error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004106 ALOGV("%s: exit: ret %d", __func__, ret);
4107 return ret;
4108}
4109
4110static void adev_close_output_stream(struct audio_hw_device *dev,
4111 struct audio_stream_out *stream)
4112{
4113 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004114 (void)dev;
4115
4116 ALOGV("%s: enter", __func__);
4117 out_standby(&stream->common);
4118 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4119 destroy_offload_callback_thread(out);
4120
4121 if (out->compr_config.codec != NULL)
4122 free(out->compr_config.codec);
4123 }
4124 pthread_cond_destroy(&out->cond);
4125 pthread_mutex_destroy(&out->lock);
4126 free(stream);
4127 ALOGV("%s: exit", __func__);
4128}
4129
4130static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4131{
4132 struct audio_device *adev = (struct audio_device *)dev;
4133 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004134 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004135#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004136 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004137#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004138 int ret;
4139
4140 ALOGV("%s: enter: %s", __func__, kvpairs);
4141
4142 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004143
Andreas Schneider05bc1882017-02-09 14:03:11 +01004144 /******************************************************
4145 *** BT SCO
4146 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004147 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4148 if (ret >= 0) {
4149 /* When set to false, HAL should disable EC and NS
4150 * But it is currently not supported.
4151 */
4152 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004153 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004154 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004155 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004156 }
4157
Andreas Schneider05bc1882017-02-09 14:03:11 +01004158 ret = str_parms_get_str(parms,
4159 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4160 value,
4161 sizeof(value));
4162 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01004163 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4164 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01004165 } else {
4166 adev->voice.bluetooth_wb = false;
4167 }
4168 }
4169
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004170 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4171 if (ret >= 0) {
4172 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4173 adev->screen_off = false;
4174 else
4175 adev->screen_off = true;
4176 }
4177
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004178#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004179 ret = str_parms_get_int(parms, "rotation", &val);
4180 if (ret >= 0) {
4181 bool reverse_speakers = false;
4182 switch(val) {
4183 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4184 relative to the user when the device is rotated 90deg from its default rotation. This
4185 assumption is device-specific, not platform-specific like this code. */
4186 case 270:
4187 reverse_speakers = true;
4188 break;
4189 case 0:
4190 case 90:
4191 case 180:
4192 break;
4193 default:
4194 ALOGE("%s: unexpected rotation of %d", __func__, val);
4195 }
4196 pthread_mutex_lock(&adev->lock);
4197 if (adev->speaker_lr_swap != reverse_speakers) {
4198 adev->speaker_lr_swap = reverse_speakers;
4199 /* only update the selected device if there is active pcm playback */
4200 struct audio_usecase *usecase;
4201 struct listnode *node;
4202 list_for_each(node, &adev->usecase_list) {
4203 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4204 if (usecase->type == PCM_PLAYBACK) {
4205 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004206 break;
4207 }
4208 }
4209 }
4210 pthread_mutex_unlock(&adev->lock);
4211 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004212#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004213
4214 str_parms_destroy(parms);
4215
4216 if (ret > 0)
4217 ret = 0;
4218
4219 ALOGV("%s: exit with code(%d)", __func__, ret);
4220 return ret;
4221}
4222
4223static char* adev_get_parameters(const struct audio_hw_device *dev,
4224 const char *keys)
4225{
4226 (void)dev;
4227 (void)keys;
4228
4229 return strdup("");
4230}
4231
4232static int adev_init_check(const struct audio_hw_device *dev)
4233{
4234 (void)dev;
4235
4236 return 0;
4237}
4238
4239static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4240{
4241 int ret = 0;
4242 struct audio_device *adev = (struct audio_device *)dev;
4243 pthread_mutex_lock(&adev->lock);
4244 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004245 adev->voice.volume = volume;
4246 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004247 pthread_mutex_unlock(&adev->lock);
4248 return ret;
4249}
4250
4251static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4252{
4253 (void)dev;
4254 (void)volume;
4255
4256 return -ENOSYS;
4257}
4258
4259static int adev_get_master_volume(struct audio_hw_device *dev,
4260 float *volume)
4261{
4262 (void)dev;
4263 (void)volume;
4264
4265 return -ENOSYS;
4266}
4267
4268static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4269{
4270 (void)dev;
4271 (void)muted;
4272
4273 return -ENOSYS;
4274}
4275
4276static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4277{
4278 (void)dev;
4279 (void)muted;
4280
4281 return -ENOSYS;
4282}
4283
4284static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4285{
4286 struct audio_device *adev = (struct audio_device *)dev;
4287
4288 pthread_mutex_lock(&adev->lock);
4289 if (adev->mode != mode) {
4290 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004291 if (amplifier_set_mode(mode) != 0) {
4292 ALOGE("Failed setting amplifier mode");
4293 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004294 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004295
4296 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4297 stop_voice_call(adev);
4298 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004299 }
4300 pthread_mutex_unlock(&adev->lock);
4301 return 0;
4302}
4303
4304static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4305{
4306 struct audio_device *adev = (struct audio_device *)dev;
4307 int err = 0;
4308
4309 pthread_mutex_lock(&adev->lock);
4310 adev->mic_mute = state;
4311
4312 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004313 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004314 }
4315
4316 pthread_mutex_unlock(&adev->lock);
4317 return err;
4318}
4319
4320static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4321{
4322 struct audio_device *adev = (struct audio_device *)dev;
4323
4324 *state = adev->mic_mute;
4325
4326 return 0;
4327}
4328
4329static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4330 const struct audio_config *config)
4331{
4332 (void)dev;
4333
4334 /* NOTE: we default to built in mic which may cause a mismatch between what we
4335 * report here and the actual buffer size
4336 */
4337 return get_input_buffer_size(config->sample_rate,
4338 config->format,
4339 audio_channel_count_from_in_mask(config->channel_mask),
4340 PCM_CAPTURE /* usecase_type */,
4341 AUDIO_DEVICE_IN_BUILTIN_MIC);
4342}
4343
4344static int adev_open_input_stream(struct audio_hw_device *dev,
4345 audio_io_handle_t handle __unused,
4346 audio_devices_t devices,
4347 struct audio_config *config,
4348 struct audio_stream_in **stream_in,
4349 audio_input_flags_t flags,
4350 const char *address __unused,
4351 audio_source_t source)
4352{
4353 struct audio_device *adev = (struct audio_device *)dev;
4354 struct stream_in *in;
4355 struct pcm_device_profile *pcm_profile;
4356
4357 ALOGV("%s: enter", __func__);
4358
4359 *stream_in = NULL;
4360 if (check_input_parameters(config->sample_rate, config->format,
4361 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4362 return -EINVAL;
4363
4364 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4365 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4366 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4367 pcm_profile = get_pcm_device(usecase_type, devices);
4368 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4369 // a low latency profile may not exist for that device, fall back
4370 // to regular capture. the MixerThread automatically changes
4371 // to non-fast capture based on the buffer size.
4372 flags &= ~AUDIO_INPUT_FLAG_FAST;
4373 usecase_type = PCM_CAPTURE;
4374 pcm_profile = get_pcm_device(usecase_type, devices);
4375 }
4376 if (pcm_profile == NULL)
4377 return -EINVAL;
4378
4379 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004380 if (in == NULL) {
4381 return -ENOMEM;
4382 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004383
4384 in->stream.common.get_sample_rate = in_get_sample_rate;
4385 in->stream.common.set_sample_rate = in_set_sample_rate;
4386 in->stream.common.get_buffer_size = in_get_buffer_size;
4387 in->stream.common.get_channels = in_get_channels;
4388 in->stream.common.get_format = in_get_format;
4389 in->stream.common.set_format = in_set_format;
4390 in->stream.common.standby = in_standby;
4391 in->stream.common.dump = in_dump;
4392 in->stream.common.set_parameters = in_set_parameters;
4393 in->stream.common.get_parameters = in_get_parameters;
4394 in->stream.common.add_audio_effect = in_add_audio_effect;
4395 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4396 in->stream.set_gain = in_set_gain;
4397 in->stream.read = in_read;
4398 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004399 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004400
4401 in->devices = devices;
4402 in->source = source;
4403 in->dev = adev;
4404 in->standby = 1;
4405 in->main_channels = config->channel_mask;
4406 in->requested_rate = config->sample_rate;
4407 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4408 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4409 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004410 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004411 /* HW codec is limited to default channels. No need to update with
4412 * requested channels */
4413 in->config = pcm_profile->config;
4414
4415 /* Update config params with the requested sample rate and channels */
4416 if (source == AUDIO_SOURCE_HOTWORD) {
4417 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4418 } else {
4419 in->usecase = USECASE_AUDIO_CAPTURE;
4420 }
4421 in->usecase_type = usecase_type;
4422
4423 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4424 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4425
4426 in->is_fastcapture_affinity_set = false;
4427
4428 *stream_in = &in->stream;
4429 ALOGV("%s: exit", __func__);
4430 return 0;
4431}
4432
4433static void adev_close_input_stream(struct audio_hw_device *dev,
4434 struct audio_stream_in *stream)
4435{
4436 struct audio_device *adev = (struct audio_device *)dev;
4437 struct stream_in *in = (struct stream_in*)stream;
4438 ALOGV("%s", __func__);
4439
4440 /* prevent concurrent out_set_parameters, or out_write from standby */
4441 pthread_mutex_lock(&adev->lock_inputs);
4442
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004443 if (in->read_buf) {
4444 free(in->read_buf);
4445 in->read_buf = NULL;
4446 }
4447
4448 if (in->resampler) {
4449 release_resampler(in->resampler);
4450 in->resampler = NULL;
4451 }
4452
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004453#ifdef PREPROCESSING_ENABLED
4454 int i;
4455
4456 for (i=0; i<in->num_preprocessors; i++) {
4457 free(in->preprocessors[i].channel_configs);
4458 }
4459
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004460 if (in->proc_buf_in) {
4461 free(in->proc_buf_in);
4462 in->proc_buf_in = NULL;
4463 }
4464
4465 if (in->proc_buf_out) {
4466 free(in->proc_buf_out);
4467 in->proc_buf_out = NULL;
4468 }
4469
4470 if (in->ref_buf) {
4471 free(in->ref_buf);
4472 in->ref_buf = NULL;
4473 }
4474
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004475#endif
4476
4477 in_standby_l(in);
4478 free(stream);
4479
4480 pthread_mutex_unlock(&adev->lock_inputs);
4481
4482 return;
4483}
4484
4485static int adev_dump(const audio_hw_device_t *device, int fd)
4486{
4487 (void)device;
4488 (void)fd;
4489
4490 return 0;
4491}
4492
4493static int adev_close(hw_device_t *device)
4494{
4495 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004496 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004497 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004498 if (audio_device_ref_count == 0) {
4499 if (amplifier_close() != 0) {
4500 ALOGE("Amplifier close failed");
4501 }
4502 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004503 free(adev->snd_dev_ref_cnt);
4504 free_mixer_list(adev);
4505 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004506
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004507 adev = NULL;
4508
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004509 return 0;
4510}
4511
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004512/* This returns true if the input parameter looks at all plausible as a low latency period size,
4513 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4514 * just that it _might_ work.
4515 */
4516static bool period_size_is_plausible_for_low_latency(int period_size)
4517{
4518 switch (period_size) {
4519 case 64:
4520 case 96:
4521 case 128:
4522 case 192:
4523 case 256:
4524 return true;
4525 default:
4526 return false;
4527 }
4528}
4529
4530static int adev_open(const hw_module_t *module, const char *name,
4531 hw_device_t **device)
4532{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004533 ALOGV("%s: enter", __func__);
4534 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4535
Andreas Schneider56204f62017-01-31 08:17:32 +01004536 *device = NULL;
4537
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004538 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004539 if (adev == NULL) {
4540 return -ENOMEM;
4541 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004542
4543 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4544 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4545 adev->device.common.module = (struct hw_module_t *)module;
4546 adev->device.common.close = adev_close;
4547
4548 adev->device.init_check = adev_init_check;
4549 adev->device.set_voice_volume = adev_set_voice_volume;
4550 adev->device.set_master_volume = adev_set_master_volume;
4551 adev->device.get_master_volume = adev_get_master_volume;
4552 adev->device.set_master_mute = adev_set_master_mute;
4553 adev->device.get_master_mute = adev_get_master_mute;
4554 adev->device.set_mode = adev_set_mode;
4555 adev->device.set_mic_mute = adev_set_mic_mute;
4556 adev->device.get_mic_mute = adev_get_mic_mute;
4557 adev->device.set_parameters = adev_set_parameters;
4558 adev->device.get_parameters = adev_get_parameters;
4559 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4560 adev->device.open_output_stream = adev_open_output_stream;
4561 adev->device.close_output_stream = adev_close_output_stream;
4562 adev->device.open_input_stream = adev_open_input_stream;
4563 adev->device.close_input_stream = adev_close_input_stream;
4564 adev->device.dump = adev_dump;
4565
4566 /* Set the default route before the PCM stream is opened */
4567 adev->mode = AUDIO_MODE_NORMAL;
4568 adev->active_input = NULL;
4569 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004570
4571 adev->voice.volume = 1.0f;
4572 adev->voice.bluetooth_nrec = true;
4573 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004574 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004575
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004576 /* adev->cur_hdmi_channels = 0; by calloc() */
4577 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004578 if (adev->snd_dev_ref_cnt == NULL) {
4579 free(adev);
4580 return -ENOMEM;
4581 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004582
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004583 adev->ns_in_voice_rec = false;
4584
4585 list_init(&adev->usecase_list);
4586
4587 if (mixer_init(adev) != 0) {
4588 free(adev->snd_dev_ref_cnt);
4589 free(adev);
4590 ALOGE("%s: Failed to init, aborting.", __func__);
4591 *device = NULL;
4592 return -EINVAL;
4593 }
4594
4595 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4596 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4597 if (adev->offload_fx_lib == NULL) {
4598 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4599 } else {
4600 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4601 adev->offload_fx_start_output =
4602 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4603 "visualizer_hal_start_output");
4604 adev->offload_fx_stop_output =
4605 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4606 "visualizer_hal_stop_output");
4607 }
4608 }
4609
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004610 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4611 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4612 if (adev->sound_trigger_lib == NULL) {
4613 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4614 } else {
4615 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4616 adev->sound_trigger_open_for_streaming =
4617 (int (*)(void))dlsym(adev->sound_trigger_lib,
4618 "sound_trigger_open_for_streaming");
4619 adev->sound_trigger_read_samples =
4620 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4621 "sound_trigger_read_samples");
4622 adev->sound_trigger_close_for_streaming =
4623 (int (*)(int))dlsym(adev->sound_trigger_lib,
4624 "sound_trigger_close_for_streaming");
4625 if (!adev->sound_trigger_open_for_streaming ||
4626 !adev->sound_trigger_read_samples ||
4627 !adev->sound_trigger_close_for_streaming) {
4628
4629 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4630 adev->sound_trigger_open_for_streaming = 0;
4631 adev->sound_trigger_read_samples = 0;
4632 adev->sound_trigger_close_for_streaming = 0;
4633 }
4634 }
4635 }
4636
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004637 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004638 if (adev->voice.session == NULL) {
4639 ALOGE("%s: Failed to initialize voice session data", __func__);
4640
4641 free(adev->snd_dev_ref_cnt);
4642 free(adev);
4643
4644 *device = NULL;
4645 return -EINVAL;
4646 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004647
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004648 if (amplifier_open() != 0) {
4649 ALOGE("Amplifier initialization failed");
4650 }
4651
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004652 *device = &adev->device.common;
4653
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004654 audio_device_ref_count++;
4655
4656 char value[PROPERTY_VALUE_MAX];
4657 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4658 int trial = atoi(value);
4659 if (period_size_is_plausible_for_low_latency(trial)) {
4660
4661 pcm_device_playback.config.period_size = trial;
4662 pcm_device_playback.config.start_threshold =
4663 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4664 pcm_device_playback.config.stop_threshold =
4665 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4666
4667 pcm_device_capture_low_latency.config.period_size = trial;
4668 }
4669 }
4670
4671 ALOGV("%s: exit", __func__);
4672 return 0;
4673}
4674
4675static struct hw_module_methods_t hal_module_methods = {
4676 .open = adev_open,
4677};
4678
4679struct audio_module HAL_MODULE_INFO_SYM = {
4680 .common = {
4681 .tag = HARDWARE_MODULE_TAG,
4682 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4683 .hal_api_version = HARDWARE_HAL_API_VERSION,
4684 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004685 .name = "Samsung Audio HAL",
4686 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004687 .methods = &hal_module_methods,
4688 },
4689};