blob: 1ede8e1926ce023f4170eb798cb95106c9d5106e [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
542 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
543 audio_route = audio_route_init(card, mixer_path);
544 if (!audio_route) {
545 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
546 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100547 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100548 goto error;
549 }
550 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100551 if (mixer_card == NULL) {
552 ret = -ENOMEM;
553 goto error;
554 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100555 mixer_card->card = card;
556 mixer_card->mixer = mixer;
557 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100558
559 /* Do not sleep on first enable_snd_device() */
560 mixer_card->dsp_poweroff_time.tv_sec = 1;
561 mixer_card->dsp_poweroff_time.tv_nsec = 0;
562
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100563 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
564 }
565 }
566
567 return 0;
568
569error:
570 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100571 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100572}
573
574static const char *get_snd_device_name(snd_device_t snd_device)
575{
576 const char *name = NULL;
577
Andreas Schneideradb788d2017-02-13 15:19:36 +0100578 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100579 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100580 name = device_table[snd_device];
581
582 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
583
584 return name;
585}
586
587static const char *get_snd_device_display_name(snd_device_t snd_device)
588{
589 const char *name = get_snd_device_name(snd_device);
590
591 if (name == NULL)
592 name = "SND DEVICE NOT FOUND";
593
594 return name;
595}
596
597static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
598{
599 int i;
600
601 devices &= ~AUDIO_DEVICE_BIT_IN;
602 for (i = 0; pcm_devices[i] != NULL; i++) {
603 if ((pcm_devices[i]->type == uc_type) &&
604 (devices & pcm_devices[i]->devices))
605 break;
606 }
607 return pcm_devices[i];
608}
609
610static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
611 audio_usecase_t uc_id)
612{
613 struct audio_usecase *usecase;
614 struct listnode *node;
615
616 list_for_each(node, &adev->usecase_list) {
617 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
618 if (usecase->id == uc_id)
619 return usecase;
620 }
621 return NULL;
622}
623
624static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
625 usecase_type_t type)
626{
627 struct audio_usecase *usecase;
628 struct listnode *node;
629
630 list_for_each(node, &adev->usecase_list) {
631 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
632 if (usecase->type & type)
633 return usecase;
634 }
635 return NULL;
636}
637
638/* always called with adev lock held */
639static int set_voice_volume_l(struct audio_device *adev, float volume)
640{
641 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100642
643 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100644 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100645 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100646
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100647 return err;
648}
649
650
651static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
652{
653
654 audio_mode_t mode = adev->mode;
655 snd_device_t snd_device = SND_DEVICE_NONE;
656
657 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
658 if (devices == AUDIO_DEVICE_NONE ||
659 devices & AUDIO_DEVICE_BIT_IN) {
660 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
661 goto exit;
662 }
663
664 if (mode == AUDIO_MODE_IN_CALL) {
665 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
666 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100667 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300668 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100669 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100670 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
671 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
672 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100673 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100674 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100675
676 if (voice_session_uses_wideband(adev->voice.session)) {
677 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
678 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
679 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300680 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100681 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100682 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
683 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
684 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
685 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
686 }
687 }
688
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100689 if (snd_device != SND_DEVICE_NONE) {
690 goto exit;
691 }
692 }
693
694 if (popcount(devices) == 2) {
695 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
696 AUDIO_DEVICE_OUT_SPEAKER)) {
697 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
698 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
699 AUDIO_DEVICE_OUT_SPEAKER)) {
700 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
701 } else {
702 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
703 goto exit;
704 }
705 if (snd_device != SND_DEVICE_NONE) {
706 goto exit;
707 }
708 }
709
710 if (popcount(devices) != 1) {
711 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
712 goto exit;
713 }
714
715 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
716 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
717 snd_device = SND_DEVICE_OUT_HEADPHONES;
718 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
719 snd_device = SND_DEVICE_OUT_SPEAKER;
720 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
721 snd_device = SND_DEVICE_OUT_BT_SCO;
722 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100723 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100724 } else {
725 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
726 }
727exit:
728 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
729 return snd_device;
730}
731
732static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
733{
734 audio_source_t source;
735 audio_mode_t mode = adev->mode;
736 audio_devices_t in_device;
737 audio_channel_mask_t channel_mask;
738 snd_device_t snd_device = SND_DEVICE_NONE;
739 struct stream_in *active_input = NULL;
740 struct audio_usecase *usecase;
741
742 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
743 if (usecase != NULL) {
744 active_input = (struct stream_in *)usecase->stream;
745 }
746 source = (active_input == NULL) ?
747 AUDIO_SOURCE_DEFAULT : active_input->source;
748
Andreas Schneider757e2d82017-02-10 19:28:35 +0100749 in_device = (active_input == NULL) ?
750 AUDIO_DEVICE_NONE :
751 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100752 channel_mask = (active_input == NULL) ?
753 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
754
755 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
756 __func__, out_device, in_device);
757 if (mode == AUDIO_MODE_IN_CALL) {
758 if (out_device == AUDIO_DEVICE_NONE) {
759 ALOGE("%s: No output device set for voice call", __func__);
760 goto exit;
761 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100762
Andreas Schneider82f32482017-02-06 09:00:48 +0100763 snd_device = SND_DEVICE_IN_VOICE_MIC;
764 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100765 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100766 }
767
768 if (voice_session_uses_twomic(adev->voice.session)) {
769 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
770 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
771 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
772 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
773 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
774 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100775 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100776
777 if (voice_session_uses_wideband(adev->voice.session)) {
778 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
779 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
780 }
781
782 if (voice_session_uses_twomic(adev->voice.session)) {
783 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
784 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
785 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
786 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
787 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
788 }
789 }
790 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100791
792 /* BT SCO */
793 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
794 snd_device = SND_DEVICE_IN_VOICE_MIC;
795
796 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300797 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100798 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300799 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100800 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300801 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100802 } else if (voice_session_uses_twomic(adev->voice.session)) {
803 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
804 }
805 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100806 } else if (source == AUDIO_SOURCE_CAMCORDER) {
807 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
808 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
809 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
810 }
811 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
812 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100813 if (snd_device == SND_DEVICE_NONE) {
814 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
815 }
816 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
817 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
818 }
819 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
820 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
821 in_device = AUDIO_DEVICE_IN_BACK_MIC;
822 if (active_input) {
823 if (active_input->enable_aec) {
824 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
825 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
826 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
827 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
828 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
829 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100830 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100831 }
832 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
833 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
834 }
835 }
836 /* TODO: set echo reference */
837 }
838 } else if (source == AUDIO_SOURCE_DEFAULT) {
839 goto exit;
840 }
841
842
843 if (snd_device != SND_DEVICE_NONE) {
844 goto exit;
845 }
846
847 if (in_device != AUDIO_DEVICE_NONE &&
848 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
849 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
850 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100851 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100852 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
853 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
854 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
855 snd_device = SND_DEVICE_IN_HEADSET_MIC;
856 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
857 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
858 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
859 snd_device = SND_DEVICE_IN_HDMI_MIC;
860 } else {
861 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100862 ALOGW("%s: Using default earpiece-mic", __func__);
863 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100864 }
865 } else {
866 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100867 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100868 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
869 snd_device = SND_DEVICE_IN_HEADSET_MIC;
870 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
871 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
872 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100873 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100874 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
875 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
876 } else {
877 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100878 ALOGW("%s: Using default earpiece-mic", __func__);
879 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100880 }
881 }
882exit:
883 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
884 return snd_device;
885}
886
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100887#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100888static int set_hdmi_channels(struct audio_device *adev, int channel_count)
889{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100890 (void)adev;
891 (void)channel_count;
892 /* TODO */
893
894 return 0;
895}
896
897static int edid_get_max_channels(struct audio_device *adev)
898{
899 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100900 (void)adev;
901
902 /* TODO */
903 return max_channels;
904}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100905#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100906
907/* Delay in Us */
908static int64_t render_latency(audio_usecase_t usecase)
909{
910 (void)usecase;
911 /* TODO */
912 return 0;
913}
914
915static int enable_snd_device(struct audio_device *adev,
916 struct audio_usecase *uc_info,
917 snd_device_t snd_device,
918 bool update_mixer)
919{
920 struct mixer_card *mixer_card;
921 struct listnode *node;
922 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100923#ifdef DSP_POWEROFF_DELAY
924 struct timespec activation_time;
925 struct timespec elapsed_time;
926#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100927
928 if (snd_device_name == NULL)
929 return -EINVAL;
930
931 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
932 ALOGV("Request to enable combo device: enable individual devices\n");
933 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
934 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
935 return 0;
936 }
937 adev->snd_dev_ref_cnt[snd_device]++;
938 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
939 ALOGV("%s: snd_device(%d: %s) is already active",
940 __func__, snd_device, snd_device_name);
941 return 0;
942 }
943
944 ALOGV("%s: snd_device(%d: %s)", __func__,
945 snd_device, snd_device_name);
946
947 list_for_each(node, &uc_info->mixer_list) {
948 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100949
950#ifdef DSP_POWEROFF_DELAY
951 clock_gettime(CLOCK_MONOTONIC, &activation_time);
952
Andreas Schneider58735a92017-02-13 16:48:17 +0100953 elapsed_time = time_spec_diff(activation_time,
954 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100955 if (elapsed_time.tv_sec == 0) {
956 long elapsed_usec = elapsed_time.tv_nsec / 1000;
957
958 if (elapsed_usec < DSP_POWEROFF_DELAY) {
959 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
960 }
961 }
962 update_mixer = true;
963#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200964
965 amplifier_enable_devices(snd_device, true);
966
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100967 audio_route_apply_path(mixer_card->audio_route, snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100968 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100969 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +0100970 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100971 }
972
973 return 0;
974}
975
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100976int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100977 struct audio_usecase *uc_info,
978 snd_device_t snd_device,
979 bool update_mixer)
980{
981 struct mixer_card *mixer_card;
982 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100983 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100984 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100985 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100986
987 if (snd_device_name == NULL)
988 return -EINVAL;
989
990 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
991 ALOGV("Request to disable combo device: disable individual devices\n");
992 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
993 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
994 return 0;
995 }
996
997 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
998 ALOGE("%s: device ref cnt is already 0", __func__);
999 return -EINVAL;
1000 }
1001 adev->snd_dev_ref_cnt[snd_device]--;
1002 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
1003 ALOGV("%s: snd_device(%d: %s)", __func__,
1004 snd_device, snd_device_name);
1005 list_for_each(node, &uc_info->mixer_list) {
1006 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +01001007#ifdef DSP_POWEROFF_DELAY
1008 update_mixer = true;
1009#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001010 audio_route_reset_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +01001011 if (out_uc_info != NULL) {
1012 /*
1013 * Cycle the rx device to eliminate routing conflicts.
1014 * This prevents issues when an input route shares mixer controls with an output
1015 * route.
1016 */
1017 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
1018 audio_route_apply_path(mixer_card->audio_route, out_snd_device_name);
1019 }
Andreas Schneider759368f2017-02-02 16:11:14 +01001020 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001021 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +01001022 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001023
1024 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +01001025#ifdef DSP_POWEROFF_DELAY
1026 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
1027#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001028 }
1029 }
1030 return 0;
1031}
1032
1033static int select_devices(struct audio_device *adev,
1034 audio_usecase_t uc_id)
1035{
1036 snd_device_t out_snd_device = SND_DEVICE_NONE;
1037 snd_device_t in_snd_device = SND_DEVICE_NONE;
1038 struct audio_usecase *usecase = NULL;
1039 struct audio_usecase *vc_usecase = NULL;
1040 struct listnode *node;
1041 struct stream_in *active_input = NULL;
1042 struct stream_out *active_out;
1043 struct mixer_card *mixer_card;
1044
1045 ALOGV("%s: usecase(%d)", __func__, uc_id);
1046
1047 if (uc_id == USECASE_AUDIO_CAPTURE_HOTWORD)
1048 return 0;
1049
1050 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1051 if (usecase != NULL) {
1052 active_input = (struct stream_in *)usecase->stream;
1053 }
1054
1055 usecase = get_usecase_from_id(adev, uc_id);
1056 if (usecase == NULL) {
1057 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1058 return -EINVAL;
1059 }
1060 active_out = (struct stream_out *)usecase->stream;
1061
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001062
1063 /*
1064 * If the voice call is active, use the sound devices of voice call usecase
1065 * so that it would not result any device switch. All the usecases will
1066 * be switched to new device when select_devices() is called for voice call
1067 * usecase.
1068 */
1069 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1070 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1071 if (vc_usecase == NULL) {
1072 ALOGE("%s: Could not find the voice call usecase", __func__);
1073 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001074 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1075 get_snd_device_display_name(vc_usecase->out_snd_device),
1076 get_snd_device_display_name(vc_usecase->in_snd_device));
1077 usecase->devices = vc_usecase->devices;
1078 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001079 }
1080 }
1081
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001082 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001083 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001084 prepare_voice_session(adev->voice.session, active_out->devices);
1085 out_snd_device = get_output_snd_device(adev, active_out->devices);
1086 in_snd_device = get_input_snd_device(adev, active_out->devices);
1087 } else if (usecase->type == PCM_PLAYBACK) {
1088 usecase->devices = active_out->devices;
1089 in_snd_device = SND_DEVICE_NONE;
1090 if (out_snd_device == SND_DEVICE_NONE) {
1091 out_snd_device = get_output_snd_device(adev, active_out->devices);
1092 if (active_out == adev->primary_output &&
1093 active_input &&
1094 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1095 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001096 }
1097 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001098 } else if (usecase->type == PCM_CAPTURE) {
1099 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1100 out_snd_device = SND_DEVICE_NONE;
1101 if (in_snd_device == SND_DEVICE_NONE) {
1102 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1103 adev->primary_output && !adev->primary_output->standby) {
1104 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1105 } else {
1106 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001107 }
1108 }
1109 }
1110
1111 if (out_snd_device == usecase->out_snd_device &&
1112 in_snd_device == usecase->in_snd_device) {
1113 return 0;
1114 }
1115
1116 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1117 out_snd_device, get_snd_device_display_name(out_snd_device),
1118 in_snd_device, get_snd_device_display_name(in_snd_device));
1119
1120
1121 /* Disable current sound devices */
1122 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001123 disable_snd_device(adev, usecase, usecase->out_snd_device, false);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001124 }
1125
1126 if (usecase->in_snd_device != SND_DEVICE_NONE) {
1127 disable_snd_device(adev, usecase, usecase->in_snd_device, false);
1128 }
1129
1130 /* Enable new sound devices */
1131 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001132 /* We need to update the audio path if we switch the out devices */
1133 if (adev->voice.in_call) {
1134 set_voice_session_audio_path(adev->voice.session);
1135 }
1136
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001137 enable_snd_device(adev, usecase, out_snd_device, false);
1138 }
1139
1140 if (in_snd_device != SND_DEVICE_NONE) {
1141 enable_snd_device(adev, usecase, in_snd_device, false);
1142 }
1143
1144 list_for_each(node, &usecase->mixer_list) {
1145 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
1146 audio_route_update_mixer(mixer_card->audio_route);
1147 }
1148
1149 usecase->in_snd_device = in_snd_device;
1150 usecase->out_snd_device = out_snd_device;
1151
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001152 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1153 amplifier_set_input_devices(in_snd_device);
1154 amplifier_set_output_devices(out_snd_device);
1155
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001156 return 0;
1157}
1158
1159
1160static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1161static int do_in_standby_l(struct stream_in *in);
1162
1163#ifdef PREPROCESSING_ENABLED
1164static void get_capture_reference_delay(struct stream_in *in,
1165 size_t frames __unused,
1166 struct echo_reference_buffer *buffer)
1167{
1168 ALOGVV("%s: enter:)", __func__);
1169
1170 /* read frames available in kernel driver buffer */
1171 unsigned int kernel_frames;
1172 struct timespec tstamp;
1173 long buf_delay;
1174 long kernel_delay;
1175 long delay_ns;
1176 struct pcm_device *ref_device;
1177 long rsmp_delay = 0;
1178
1179 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1180 struct pcm_device, stream_list_node);
1181
1182 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1183 buffer->time_stamp.tv_sec = 0;
1184 buffer->time_stamp.tv_nsec = 0;
1185 buffer->delay_ns = 0;
1186 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1187 return;
1188 }
1189
1190 /* adjust render time stamp with delay added by current driver buffer.
1191 * Add the duration of current frame as we want the render time of the last
1192 * sample being written. */
1193
1194 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1195
1196 buffer->time_stamp = tstamp;
1197 buffer->delay_ns = kernel_delay;
1198
1199 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1200 " delay_ns: [%d] , frames:[%zd]",
1201 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1202}
1203
1204static void get_capture_delay(struct stream_in *in,
1205 size_t frames __unused,
1206 struct echo_reference_buffer *buffer)
1207{
1208 ALOGVV("%s: enter:)", __func__);
1209 /* read frames available in kernel driver buffer */
1210 unsigned int kernel_frames;
1211 struct timespec tstamp;
1212 long buf_delay;
1213 long rsmp_delay;
1214 long kernel_delay;
1215 long delay_ns;
1216 struct pcm_device *pcm_device;
1217
1218 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1219 struct pcm_device, stream_list_node);
1220
1221 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1222 buffer->time_stamp.tv_sec = 0;
1223 buffer->time_stamp.tv_nsec = 0;
1224 buffer->delay_ns = 0;
1225 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1226 return;
1227 }
1228
1229 /* read frames available in audio HAL input buffer
1230 * add number of frames being read as we want the capture time of first sample
1231 * in current buffer */
1232 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1233 * at requested sampling rate */
1234 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1235 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1236
1237 /* add delay introduced by resampler */
1238 rsmp_delay = 0;
1239 if (in->resampler) {
1240 rsmp_delay = in->resampler->delay_ns(in->resampler);
1241 }
1242
1243 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1244
1245 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1246
1247 buffer->time_stamp = tstamp;
1248 buffer->delay_ns = delay_ns;
1249 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1250 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1251 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1252 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1253 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1254 in->read_buf_frames, in->proc_buf_frames, frames);
1255}
1256
1257static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1258{
1259 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1260 struct echo_reference_buffer b;
1261 b.delay_ns = 0;
1262 struct pcm_device *pcm_device;
1263
1264 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1265 struct pcm_device, stream_list_node);
1266
1267 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1268 "b.frame_count = [%zd]",
1269 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1270 if (in->ref_buf_frames < frames) {
1271 if (in->ref_buf_size < frames) {
1272 in->ref_buf_size = frames;
1273 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1274 ALOG_ASSERT((in->ref_buf != NULL),
1275 "update_echo_reference() failed to reallocate ref_buf");
1276 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1277 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1278 }
1279 b.frame_count = frames - in->ref_buf_frames;
1280 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1281
1282 get_capture_delay(in, frames, &b);
1283
1284 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1285 {
1286 in->ref_buf_frames += b.frame_count;
1287 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1288 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1289 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1290 }
1291 } else
1292 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1293 return b.delay_ns;
1294}
1295
1296static int set_preprocessor_param(effect_handle_t handle,
1297 effect_param_t *param)
1298{
1299 uint32_t size = sizeof(int);
1300 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1301 param->vsize;
1302
1303 int status = (*handle)->command(handle,
1304 EFFECT_CMD_SET_PARAM,
1305 sizeof (effect_param_t) + psize,
1306 param,
1307 &size,
1308 &param->status);
1309 if (status == 0)
1310 status = param->status;
1311
1312 return status;
1313}
1314
1315static int set_preprocessor_echo_delay(effect_handle_t handle,
1316 int32_t delay_us)
1317{
1318 struct {
1319 effect_param_t param;
1320 uint32_t data_0;
1321 int32_t data_1;
1322 } buf;
1323 memset(&buf, 0, sizeof(buf));
1324
1325 buf.param.psize = sizeof(uint32_t);
1326 buf.param.vsize = sizeof(uint32_t);
1327 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1328 buf.data_1 = delay_us;
1329
1330 return set_preprocessor_param(handle, &buf.param);
1331}
1332
1333static void push_echo_reference(struct stream_in *in, size_t frames)
1334{
1335 ALOGVV("%s: enter:)", __func__);
1336 /* read frames from echo reference buffer and update echo delay
1337 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1338
1339 int32_t delay_us = update_echo_reference(in, frames)/1000;
1340 int32_t size_in_bytes = 0;
1341 int i;
1342 audio_buffer_t buf;
1343
1344 if (in->ref_buf_frames < frames)
1345 frames = in->ref_buf_frames;
1346
1347 buf.frameCount = frames;
1348 buf.raw = in->ref_buf;
1349
1350 for (i = 0; i < in->num_preprocessors; i++) {
1351 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1352 continue;
1353 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1354 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1355 &buf,
1356 NULL);
1357 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1358 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1359 }
1360
1361 in->ref_buf_frames -= buf.frameCount;
1362 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1363 __func__, in->ref_buf_frames, in->config.channels);
1364 if (in->ref_buf_frames) {
1365 memcpy(in->ref_buf,
1366 in->ref_buf + buf.frameCount * in->config.channels,
1367 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1368 }
1369}
1370
1371static void put_echo_reference(struct audio_device *adev,
1372 struct echo_reference_itfe *reference)
1373{
1374 ALOGV("%s: enter:)", __func__);
1375 int32_t prev_generation = adev->echo_reference_generation;
1376 struct stream_out *out = adev->primary_output;
1377
1378 if (adev->echo_reference != NULL &&
1379 reference == adev->echo_reference) {
1380 /* echo reference is taken from the low latency output stream used
1381 * for voice use cases */
1382 adev->echo_reference = NULL;
1383 android_atomic_inc(&adev->echo_reference_generation);
1384 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1385 // if the primary output is in standby or did not pick the echo reference yet
1386 // we can safely get rid of it here.
1387 // otherwise, out_write() or out_standby() will detect the change in echo reference
1388 // generation and release the echo reference owned by the stream.
1389 if ((out->echo_reference_generation != prev_generation) || out->standby)
1390 release_echo_reference(reference);
1391 } else {
1392 release_echo_reference(reference);
1393 }
1394 ALOGV("release_echo_reference");
1395 }
1396}
1397
1398static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1399 audio_format_t format __unused,
1400 uint32_t channel_count,
1401 uint32_t sampling_rate)
1402{
1403 ALOGV("%s: enter:)", __func__);
1404 put_echo_reference(adev, adev->echo_reference);
1405 /* echo reference is taken from the low latency output stream used
1406 * for voice use cases */
1407 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1408 !adev->primary_output->standby) {
1409 struct audio_stream *stream =
1410 &adev->primary_output->stream.common;
1411 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1412 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1413 ALOGV("Calling create_echo_reference");
1414 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1415 channel_count,
1416 sampling_rate,
1417 AUDIO_FORMAT_PCM_16_BIT,
1418 wr_channel_count,
1419 wr_sampling_rate,
1420 &adev->echo_reference);
1421 if (status == 0)
1422 android_atomic_inc(&adev->echo_reference_generation);
1423 }
1424 return adev->echo_reference;
1425}
1426
1427#ifdef HW_AEC_LOOPBACK
1428static int get_hw_echo_reference(struct stream_in *in)
1429{
1430 struct pcm_device_profile *ref_pcm_profile;
1431 struct pcm_device *ref_device;
1432 struct audio_device *adev = in->dev;
1433
1434 in->hw_echo_reference = false;
1435
1436 if (adev->primary_output!= NULL &&
1437 !adev->primary_output->standby &&
1438 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1439 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1440 struct audio_stream *stream = &adev->primary_output->stream.common;
1441
1442 // TODO: currently there is no low latency mode for aec reference.
1443 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1444 if (ref_pcm_profile == NULL) {
1445 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1446 __func__, pcm_device_capture_loopback_aec.devices);
1447 return -EINVAL;
1448 }
1449
1450 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001451 if (ref_device == NULL) {
1452 return -ENOMEM;
1453 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001454 ref_device->pcm_profile = ref_pcm_profile;
1455
1456 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1457 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1458
1459 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1460 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1461 pcm_close(ref_device->pcm);
1462 ref_device->pcm = NULL;
1463 return -EIO;
1464 }
1465 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1466
1467 in->hw_echo_reference = true;
1468
1469 ALOGV("%s: hw_echo_reference is true", __func__);
1470 }
1471
1472 return 0;
1473}
1474#endif
1475
1476static int get_playback_delay(struct stream_out *out,
1477 size_t frames,
1478 struct echo_reference_buffer *buffer)
1479{
1480 unsigned int kernel_frames;
1481 int status;
1482 int primary_pcm = 0;
1483 struct pcm_device *pcm_device;
1484
1485 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1486 struct pcm_device, stream_list_node);
1487
1488 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1489 if (status < 0) {
1490 buffer->time_stamp.tv_sec = 0;
1491 buffer->time_stamp.tv_nsec = 0;
1492 buffer->delay_ns = 0;
1493 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1494 "setting playbackTimestamp to 0");
1495 return status;
1496 }
1497
1498 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1499
1500 /* adjust render time stamp with delay added by current driver buffer.
1501 * Add the duration of current frame as we want the render time of the last
1502 * sample being written. */
1503 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1504 out->config.rate);
1505 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1506 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1507
1508 return 0;
1509}
1510
1511#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1512 do { \
1513 if (fct_status != 0) \
1514 status = fct_status; \
1515 else if (cmd_status != 0) \
1516 status = cmd_status; \
1517 } while(0)
1518
1519static int in_configure_reverse(struct stream_in *in)
1520{
1521 int32_t cmd_status;
1522 uint32_t size = sizeof(int);
1523 effect_config_t config;
1524 int32_t status = 0;
1525 int32_t fct_status = 0;
1526 int i;
1527 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1528 if (in->num_preprocessors > 0) {
1529 config.inputCfg.channels = in->main_channels;
1530 config.outputCfg.channels = in->main_channels;
1531 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1532 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1533 config.inputCfg.samplingRate = in->requested_rate;
1534 config.outputCfg.samplingRate = in->requested_rate;
1535 config.inputCfg.mask =
1536 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1537 config.outputCfg.mask =
1538 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1539
1540 for (i = 0; i < in->num_preprocessors; i++)
1541 {
1542 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1543 continue;
1544 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1545 in->preprocessors[i].effect_itfe,
1546 EFFECT_CMD_SET_CONFIG_REVERSE,
1547 sizeof(effect_config_t),
1548 &config,
1549 &size,
1550 &cmd_status);
1551 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1552 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1553 }
1554 }
1555 return status;
1556}
1557
1558#define MAX_NUM_CHANNEL_CONFIGS 10
1559
1560static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1561 struct effect_info_s *effect_info)
1562{
1563 /* size and format of the cmd are defined in hardware/audio_effect.h */
1564 effect_handle_t effect = effect_info->effect_itfe;
1565 uint32_t cmd_size = 2 * sizeof(uint32_t);
1566 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1567 /* reply = status + number of configs (n) + n x channel_config_t */
1568 uint32_t reply_size =
1569 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1570 int32_t reply[reply_size];
1571 int32_t cmd_status;
1572
1573 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1574 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1575 ALOG_ASSERT((effect_info->channel_configs == NULL),
1576 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1577
1578 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1579 * This error will be interpreted as if the effect supports the main_channels but does not
1580 * support any aux_channels */
1581 cmd_status = (*effect)->command(effect,
1582 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1583 cmd_size,
1584 (void*)&cmd,
1585 &reply_size,
1586 (void*)&reply);
1587
1588 if (cmd_status != 0) {
1589 ALOGV("in_read_audio_effect_channel_configs(): "
1590 "fx->command returned %d", cmd_status);
1591 return;
1592 }
1593
1594 if (reply[0] != 0) {
1595 ALOGW("in_read_audio_effect_channel_configs(): "
1596 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1597 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1598 return;
1599 }
1600
1601 /* the feature is not supported */
1602 ALOGV("in_read_audio_effect_channel_configs()(): "
1603 "Feature supported and adding %d channel configs to the list", reply[1]);
1604 effect_info->num_channel_configs = reply[1];
1605 effect_info->channel_configs =
1606 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1607 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1608}
1609
1610
1611#define NUM_IN_AUX_CNL_CONFIGS 2
1612static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1613 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1614 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1615};
1616static uint32_t in_get_aux_channels(struct stream_in *in)
1617{
1618 int i;
1619 channel_config_t new_chcfg = {0, 0};
1620
1621 if (in->num_preprocessors == 0)
1622 return 0;
1623
1624 /* do not enable dual mic configurations when capturing from other microphones than
1625 * main or sub */
1626 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1627 return 0;
1628
1629 /* retain most complex aux channels configuration compatible with requested main channels and
1630 * supported by audio driver and all pre processors */
1631 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1632 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1633 if (cur_chcfg->main_channels == in->main_channels) {
1634 size_t match_cnt;
1635 size_t idx_preproc;
1636 for (idx_preproc = 0, match_cnt = 0;
1637 /* no need to continue if at least one preprocessor doesn't match */
1638 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1639 idx_preproc++) {
1640 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1641 size_t idx_chcfg;
1642
1643 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1644 if (memcmp(effect_info->channel_configs + idx_chcfg,
1645 cur_chcfg,
1646 sizeof(channel_config_t)) == 0) {
1647 match_cnt++;
1648 break;
1649 }
1650 }
1651 }
1652 /* if all preprocessors match, we have a candidate */
1653 if (match_cnt == (size_t)in->num_preprocessors) {
1654 /* retain most complex aux channels configuration */
1655 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1656 new_chcfg = *cur_chcfg;
1657 }
1658 }
1659 }
1660 }
1661
1662 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1663
1664 return new_chcfg.aux_channels;
1665}
1666
1667static int in_configure_effect_channels(effect_handle_t effect,
1668 channel_config_t *channel_config)
1669{
1670 int status = 0;
1671 int fct_status;
1672 int32_t cmd_status;
1673 uint32_t reply_size;
1674 effect_config_t config;
1675 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1676
1677 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1678 channel_config->main_channels,
1679 channel_config->aux_channels);
1680
1681 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1682 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1683 reply_size = sizeof(effect_config_t);
1684 fct_status = (*effect)->command(effect,
1685 EFFECT_CMD_GET_CONFIG,
1686 0,
1687 NULL,
1688 &reply_size,
1689 &config);
1690 if (fct_status != 0) {
1691 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1692 return fct_status;
1693 }
1694
1695 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1696 config.outputCfg.channels = config.inputCfg.channels;
1697 reply_size = sizeof(uint32_t);
1698 fct_status = (*effect)->command(effect,
1699 EFFECT_CMD_SET_CONFIG,
1700 sizeof(effect_config_t),
1701 &config,
1702 &reply_size,
1703 &cmd_status);
1704 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1705
1706 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1707 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1708 reply_size = sizeof(uint32_t);
1709 fct_status = (*effect)->command(effect,
1710 EFFECT_CMD_SET_FEATURE_CONFIG,
1711 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1712 cmd,
1713 &reply_size,
1714 &cmd_status);
1715 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1716
1717 /* some implementations need to be re-enabled after a config change */
1718 reply_size = sizeof(uint32_t);
1719 fct_status = (*effect)->command(effect,
1720 EFFECT_CMD_ENABLE,
1721 0,
1722 NULL,
1723 &reply_size,
1724 &cmd_status);
1725 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1726
1727 return status;
1728}
1729
1730static int in_reconfigure_channels(struct stream_in *in,
1731 effect_handle_t effect,
1732 channel_config_t *channel_config,
1733 bool config_changed) {
1734
1735 int status = 0;
1736
1737 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1738 config_changed, effect);
1739
1740 /* if config changed, reconfigure all previously added effects */
1741 if (config_changed) {
1742 int i;
1743 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1744 for (i = 0; i < in->num_preprocessors; i++)
1745 {
1746 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1747 channel_config);
1748 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1749 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1750 if (cur_status != 0) {
1751 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1752 "%d with channels: [%04x][%04x]",
1753 cur_status,
1754 i,
1755 channel_config->main_channels,
1756 channel_config->aux_channels);
1757 status = cur_status;
1758 }
1759 }
1760 } else if (effect != NULL && channel_config->aux_channels) {
1761 /* if aux channels config did not change but aux channels are present,
1762 * we still need to configure the effect being added */
1763 status = in_configure_effect_channels(effect, channel_config);
1764 }
1765 return status;
1766}
1767
1768static void in_update_aux_channels(struct stream_in *in,
1769 effect_handle_t effect)
1770{
1771 uint32_t aux_channels;
1772 channel_config_t channel_config;
1773 int status;
1774
1775 aux_channels = in_get_aux_channels(in);
1776
1777 channel_config.main_channels = in->main_channels;
1778 channel_config.aux_channels = aux_channels;
1779 status = in_reconfigure_channels(in,
1780 effect,
1781 &channel_config,
1782 (aux_channels != in->aux_channels));
1783
1784 if (status != 0) {
1785 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1786 /* resetting aux channels configuration */
1787 aux_channels = 0;
1788 channel_config.aux_channels = 0;
1789 in_reconfigure_channels(in, effect, &channel_config, true);
1790 }
1791 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1792 if (in->aux_channels != aux_channels) {
1793 in->aux_channels_changed = true;
1794 in->aux_channels = aux_channels;
1795 do_in_standby_l(in);
1796 }
1797}
1798#endif
1799
1800/* This function reads PCM data and:
1801 * - resample if needed
1802 * - process if pre-processors are attached
1803 * - discard unwanted channels
1804 */
1805static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1806{
1807 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001808 size_t src_channels = in->config.channels;
1809 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1810 int i;
1811 void *proc_buf_out;
1812 struct pcm_device *pcm_device;
1813 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1814#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001815 audio_buffer_t in_buf;
1816 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001817 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1818#endif
1819
1820 /* Additional channels might be added on top of main_channels:
1821 * - aux_channels (by processing effects)
1822 * - extra channels due to HW limitations
1823 * In case of additional channels, we cannot work inplace
1824 */
1825 if (has_additional_channels)
1826 proc_buf_out = in->proc_buf_out;
1827 else
1828 proc_buf_out = buffer;
1829
1830 if (list_empty(&in->pcm_dev_list)) {
1831 ALOGE("%s: pcm device list empty", __func__);
1832 return -EINVAL;
1833 }
1834
1835 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1836 struct pcm_device, stream_list_node);
1837
1838#ifdef PREPROCESSING_ENABLED
1839 if (has_processing) {
1840 /* since all the processing below is done in frames and using the config.channels
1841 * as the number of channels, no changes is required in case aux_channels are present */
1842 while (frames_wr < frames) {
1843 /* first reload enough frames at the end of process input buffer */
1844 if (in->proc_buf_frames < (size_t)frames) {
1845 ssize_t frames_rd;
1846 if (in->proc_buf_size < (size_t)frames) {
1847 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1848 in->proc_buf_size = (size_t)frames;
1849 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1850 ALOG_ASSERT((in->proc_buf_in != NULL),
1851 "process_frames() failed to reallocate proc_buf_in");
1852 if (has_additional_channels) {
1853 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1854 ALOG_ASSERT((in->proc_buf_out != NULL),
1855 "process_frames() failed to reallocate proc_buf_out");
1856 proc_buf_out = in->proc_buf_out;
1857 }
1858 }
1859 frames_rd = read_frames(in,
1860 in->proc_buf_in +
1861 in->proc_buf_frames * in->config.channels,
1862 frames - in->proc_buf_frames);
1863 if (frames_rd < 0) {
1864 /* Return error code */
1865 frames_wr = frames_rd;
1866 break;
1867 }
1868 in->proc_buf_frames += frames_rd;
1869 }
1870
1871 if (in->echo_reference != NULL) {
1872 push_echo_reference(in, in->proc_buf_frames);
1873 }
1874
1875 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1876 * the maximum number of frames to be consumed and produced by process() */
1877 in_buf.frameCount = in->proc_buf_frames;
1878 in_buf.s16 = in->proc_buf_in;
1879 out_buf.frameCount = frames - frames_wr;
1880 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1881
1882 /* FIXME: this works because of current pre processing library implementation that
1883 * does the actual process only when the last enabled effect process is called.
1884 * The generic solution is to have an output buffer for each effect and pass it as
1885 * input to the next.
1886 */
1887 for (i = 0; i < in->num_preprocessors; i++) {
1888 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1889 &in_buf,
1890 &out_buf);
1891 }
1892
1893 /* process() has updated the number of frames consumed and produced in
1894 * in_buf.frameCount and out_buf.frameCount respectively
1895 * move remaining frames to the beginning of in->proc_buf_in */
1896 in->proc_buf_frames -= in_buf.frameCount;
1897
1898 if (in->proc_buf_frames) {
1899 memcpy(in->proc_buf_in,
1900 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1901 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1902 }
1903
1904 /* if not enough frames were passed to process(), read more and retry. */
1905 if (out_buf.frameCount == 0) {
1906 ALOGW("No frames produced by preproc");
1907 continue;
1908 }
1909
1910 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1911 frames_wr += out_buf.frameCount;
1912 } else {
1913 /* The effect does not comply to the API. In theory, we should never end up here! */
1914 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1915 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1916 frames_wr = frames;
1917 }
1918 }
1919 }
1920 else
1921#endif //PREPROCESSING_ENABLED
1922 {
1923 /* No processing effects attached */
1924 if (has_additional_channels) {
1925 /* With additional channels, we cannot use original buffer */
1926 if (in->proc_buf_size < (size_t)frames) {
1927 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1928 in->proc_buf_size = (size_t)frames;
1929 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1930 ALOG_ASSERT((in->proc_buf_out != NULL),
1931 "process_frames() failed to reallocate proc_buf_out");
1932 proc_buf_out = in->proc_buf_out;
1933 }
1934 }
1935 frames_wr = read_frames(in, proc_buf_out, frames);
1936 }
1937
1938 /* Remove all additional channels that have been added on top of main_channels:
1939 * - aux_channels
1940 * - extra channels from HW due to HW limitations
1941 * Assumption is made that the channels are interleaved and that the main
1942 * channels are first. */
1943
1944 if (has_additional_channels)
1945 {
1946 int16_t* src_buffer = (int16_t *)proc_buf_out;
1947 int16_t* dst_buffer = (int16_t *)buffer;
1948
1949 if (dst_channels == 1) {
1950 for (i = frames_wr; i > 0; i--)
1951 {
1952 *dst_buffer++ = *src_buffer;
1953 src_buffer += src_channels;
1954 }
1955 } else {
1956 for (i = frames_wr; i > 0; i--)
1957 {
1958 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1959 dst_buffer += dst_channels;
1960 src_buffer += src_channels;
1961 }
1962 }
1963 }
1964
1965 return frames_wr;
1966}
1967
1968static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1969 struct resampler_buffer* buffer)
1970{
1971 struct stream_in *in;
1972 struct pcm_device *pcm_device;
1973
1974 if (buffer_provider == NULL || buffer == NULL)
1975 return -EINVAL;
1976
1977 in = (struct stream_in *)((char *)buffer_provider -
1978 offsetof(struct stream_in, buf_provider));
1979
1980 if (list_empty(&in->pcm_dev_list)) {
1981 buffer->raw = NULL;
1982 buffer->frame_count = 0;
1983 in->read_status = -ENODEV;
1984 return -ENODEV;
1985 }
1986
1987 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1988 struct pcm_device, stream_list_node);
1989
1990 if (in->read_buf_frames == 0) {
1991 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1992 if (in->read_buf_size < in->config.period_size) {
1993 in->read_buf_size = in->config.period_size;
1994 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1995 ALOG_ASSERT((in->read_buf != NULL),
1996 "get_next_buffer() failed to reallocate read_buf");
1997 }
1998
1999 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
2000
2001 if (in->read_status != 0) {
2002 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
2003 buffer->raw = NULL;
2004 buffer->frame_count = 0;
2005 return in->read_status;
2006 }
2007 in->read_buf_frames = in->config.period_size;
2008
2009#ifdef PREPROCESSING_ENABLED
2010#ifdef HW_AEC_LOOPBACK
2011 if (in->hw_echo_reference) {
2012 struct pcm_device *temp_device = NULL;
2013 struct pcm_device *ref_device = NULL;
2014 struct listnode *node = NULL;
2015 struct echo_reference_buffer b;
2016 size_t size_hw_ref_bytes;
2017 size_t size_hw_ref_frames;
2018 int read_status = 0;
2019
2020 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
2021 struct pcm_device, stream_list_node);
2022 list_for_each(node, &in->pcm_dev_list) {
2023 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
2024 if (temp_device->pcm_profile->id == 1) {
2025 ref_device = temp_device;
2026 break;
2027 }
2028 }
2029 if (ref_device) {
2030 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
2031 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
2032 if (in->hw_ref_buf_size < size_hw_ref_frames) {
2033 in->hw_ref_buf_size = size_hw_ref_frames;
2034 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2035 ALOG_ASSERT((in->hw_ref_buf != NULL),
2036 "get_next_buffer() failed to reallocate hw_ref_buf");
2037 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2038 in->hw_ref_buf, size_hw_ref_bytes);
2039 }
2040
2041 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2042 if (read_status != 0) {
2043 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2044 b.raw = NULL;
2045 b.frame_count = 0;
2046 }
2047 else {
2048 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2049 b.raw = (void *)in->hw_ref_buf;
2050 b.frame_count = size_hw_ref_frames;
2051 if (b.delay_ns != 0)
2052 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2053 in->echo_reference->write(in->echo_reference, &b);
2054 }
2055 }
2056 }
2057#endif // HW_AEC_LOOPBACK
2058#endif // PREPROCESSING_ENABLED
2059 }
2060
2061 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2062 in->read_buf_frames : buffer->frame_count;
2063 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2064 in->config.channels;
2065 return in->read_status;
2066}
2067
2068static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2069 struct resampler_buffer* buffer)
2070{
2071 struct stream_in *in;
2072
2073 if (buffer_provider == NULL || buffer == NULL)
2074 return;
2075
2076 in = (struct stream_in *)((char *)buffer_provider -
2077 offsetof(struct stream_in, buf_provider));
2078
2079 in->read_buf_frames -= buffer->frame_count;
2080}
2081
2082/* read_frames() reads frames from kernel driver, down samples to capture rate
2083 * if necessary and output the number of frames requested to the buffer specified */
2084static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2085{
2086 ssize_t frames_wr = 0;
2087
2088 struct pcm_device *pcm_device;
2089
2090 if (list_empty(&in->pcm_dev_list)) {
2091 ALOGE("%s: pcm device list empty", __func__);
2092 return -EINVAL;
2093 }
2094
2095 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2096 struct pcm_device, stream_list_node);
2097
2098 while (frames_wr < frames) {
2099 size_t frames_rd = frames - frames_wr;
2100 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2101 __func__,frames_rd,frames_wr,in->config.channels);
2102 if (in->resampler != NULL) {
2103 in->resampler->resample_from_provider(in->resampler,
2104 (int16_t *)((char *)buffer +
2105 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2106 &frames_rd);
2107 } else {
2108 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002109 .raw = NULL,
2110 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002111 };
2112 get_next_buffer(&in->buf_provider, &buf);
2113 if (buf.raw != NULL) {
2114 memcpy((char *)buffer +
2115 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2116 buf.raw,
2117 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2118 frames_rd = buf.frame_count;
2119 }
2120 release_buffer(&in->buf_provider, &buf);
2121 }
2122 /* in->read_status is updated by getNextBuffer() also called by
2123 * in->resampler->resample_from_provider() */
2124 if (in->read_status != 0)
2125 return in->read_status;
2126
2127 frames_wr += frames_rd;
2128 }
2129 return frames_wr;
2130}
2131
2132static int in_release_pcm_devices(struct stream_in *in)
2133{
2134 struct pcm_device *pcm_device;
2135 struct listnode *node;
2136 struct listnode *next;
2137
2138 list_for_each_safe(node, next, &in->pcm_dev_list) {
2139 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2140 list_remove(node);
2141 free(pcm_device);
2142 }
2143
2144 return 0;
2145}
2146
2147static int stop_input_stream(struct stream_in *in)
2148{
2149 struct audio_usecase *uc_info;
2150 struct audio_device *adev = in->dev;
2151
2152 adev->active_input = NULL;
2153 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2154 in->usecase, use_case_table[in->usecase]);
2155 uc_info = get_usecase_from_id(adev, in->usecase);
2156 if (uc_info == NULL) {
2157 ALOGE("%s: Could not find the usecase (%d) in the list",
2158 __func__, in->usecase);
2159 return -EINVAL;
2160 }
2161
2162 /* Disable the tx device */
2163 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2164
2165 list_remove(&uc_info->adev_list_node);
2166 free(uc_info);
2167
2168 if (list_empty(&in->pcm_dev_list)) {
2169 ALOGE("%s: pcm device list empty", __func__);
2170 return -EINVAL;
2171 }
2172
2173 in_release_pcm_devices(in);
2174 list_init(&in->pcm_dev_list);
2175
2176#ifdef HW_AEC_LOOPBACK
2177 if (in->hw_echo_reference)
2178 {
2179 in->hw_echo_reference = false;
2180 }
2181#endif
2182
2183 ALOGV("%s: exit", __func__);
2184 return 0;
2185}
2186
2187static int start_input_stream(struct stream_in *in)
2188{
2189 /* Enable output device and stream routing controls */
2190 int ret = 0;
2191 bool recreate_resampler = false;
2192 struct audio_usecase *uc_info;
2193 struct audio_device *adev = in->dev;
2194 struct pcm_device_profile *pcm_profile;
2195 struct pcm_device *pcm_device;
2196
2197 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2198 adev->active_input = in;
2199 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2200 if (pcm_profile == NULL) {
2201 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2202 __func__, in->usecase);
2203 ret = -EINVAL;
2204 goto error_config;
2205 }
2206
2207 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002208 if (uc_info == NULL) {
2209 ret = -ENOMEM;
2210 goto error_config;
2211 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002212 uc_info->id = in->usecase;
2213 uc_info->type = PCM_CAPTURE;
2214 uc_info->stream = (struct audio_stream *)in;
2215 uc_info->devices = in->devices;
2216 uc_info->in_snd_device = SND_DEVICE_NONE;
2217 uc_info->out_snd_device = SND_DEVICE_NONE;
2218
2219 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002220 if (pcm_device == NULL) {
2221 free(uc_info);
2222 ret = -ENOMEM;
2223 goto error_config;
2224 }
2225
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002226 pcm_device->pcm_profile = pcm_profile;
2227 list_init(&in->pcm_dev_list);
2228 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2229
2230 list_init(&uc_info->mixer_list);
2231 list_add_tail(&uc_info->mixer_list,
2232 &adev_get_mixer_for_card(adev,
2233 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2234
2235 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2236
2237 select_devices(adev, in->usecase);
2238
2239 /* Config should be updated as profile can be changed between different calls
2240 * to this function:
2241 * - Trigger resampler creation
2242 * - Config needs to be updated */
2243 if (in->config.rate != pcm_profile->config.rate) {
2244 recreate_resampler = true;
2245 }
2246 in->config = pcm_profile->config;
2247
2248#ifdef PREPROCESSING_ENABLED
2249 if (in->aux_channels_changed) {
2250 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2251 recreate_resampler = true;
2252 }
2253#endif
2254
2255 if (in->requested_rate != in->config.rate) {
2256 recreate_resampler = true;
2257 }
2258
2259 if (recreate_resampler) {
2260 if (in->resampler) {
2261 release_resampler(in->resampler);
2262 in->resampler = NULL;
2263 }
2264 in->buf_provider.get_next_buffer = get_next_buffer;
2265 in->buf_provider.release_buffer = release_buffer;
2266 ret = create_resampler(in->config.rate,
2267 in->requested_rate,
2268 in->config.channels,
2269 RESAMPLER_QUALITY_DEFAULT,
2270 &in->buf_provider,
2271 &in->resampler);
2272 }
2273
2274#ifdef PREPROCESSING_ENABLED
2275 if (in->enable_aec && in->echo_reference == NULL) {
2276 in->echo_reference = get_echo_reference(adev,
2277 AUDIO_FORMAT_PCM_16_BIT,
2278 audio_channel_count_from_in_mask(in->main_channels),
2279 in->requested_rate
2280 );
2281 }
2282
2283#ifdef HW_AEC_LOOPBACK
2284 if (in->enable_aec) {
2285 ret = get_hw_echo_reference(in);
2286 if (ret!=0)
2287 goto error_open;
2288
2289 /* force ref buffer reallocation */
2290 in->hw_ref_buf_size = 0;
2291 }
2292#endif
2293#endif
2294
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002295 if (in->dev->voice.in_call) {
2296 ALOGV("%s: in_call, not handling PCMs", __func__);
2297 goto skip_pcm_handling;
2298 }
2299
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002300 /* Open the PCM device.
2301 * The HW is limited to support only the default pcm_profile settings.
2302 * As such a change in aux_channels will not have an effect.
2303 */
2304 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2305 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2306 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2307 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2308
2309 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2310 if (!adev->sound_trigger_open_for_streaming) {
2311 ALOGE("%s: No handle to sound trigger HAL", __func__);
2312 ret = -EIO;
2313 goto error_open;
2314 }
2315 pcm_device->pcm = NULL;
2316 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2317 if (pcm_device->sound_trigger_handle <= 0) {
2318 ALOGE("%s: Failed to open DSP for streaming", __func__);
2319 ret = -EIO;
2320 goto error_open;
2321 }
2322 ALOGV("Opened DSP successfully");
2323 } else {
2324 pcm_device->sound_trigger_handle = 0;
2325 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2326 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2327
2328 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2329 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2330 pcm_close(pcm_device->pcm);
2331 pcm_device->pcm = NULL;
2332 ret = -EIO;
2333 goto error_open;
2334 }
2335 }
2336
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002337skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002338 /* force read and proc buffer reallocation in case of frame size or
2339 * channel count change */
2340 in->proc_buf_frames = 0;
2341 in->proc_buf_size = 0;
2342 in->read_buf_size = 0;
2343 in->read_buf_frames = 0;
2344
2345 /* if no supported sample rate is available, use the resampler */
2346 if (in->resampler) {
2347 in->resampler->reset(in->resampler);
2348 }
2349
2350 ALOGV("%s: exit", __func__);
2351 return ret;
2352
2353error_open:
2354 if (in->resampler) {
2355 release_resampler(in->resampler);
2356 in->resampler = NULL;
2357 }
2358 stop_input_stream(in);
2359
2360error_config:
2361 ALOGV("%s: exit: status(%d)", __func__, ret);
2362 adev->active_input = NULL;
2363 return ret;
2364}
2365
2366void lock_input_stream(struct stream_in *in)
2367{
2368 pthread_mutex_lock(&in->pre_lock);
2369 pthread_mutex_lock(&in->lock);
2370 pthread_mutex_unlock(&in->pre_lock);
2371}
2372
2373void lock_output_stream(struct stream_out *out)
2374{
2375 pthread_mutex_lock(&out->pre_lock);
2376 pthread_mutex_lock(&out->lock);
2377 pthread_mutex_unlock(&out->pre_lock);
2378}
2379
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002380static int uc_release_pcm_devices(struct audio_usecase *usecase)
2381{
2382 struct stream_out *out = (struct stream_out *)usecase->stream;
2383 struct pcm_device *pcm_device;
2384 struct listnode *node;
2385 struct listnode *next;
2386
2387 list_for_each_safe(node, next, &out->pcm_dev_list) {
2388 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2389 list_remove(node);
2390 free(pcm_device);
2391 }
2392 list_init(&usecase->mixer_list);
2393
2394 return 0;
2395}
2396
2397static int uc_select_pcm_devices(struct audio_usecase *usecase)
2398
2399{
2400 struct stream_out *out = (struct stream_out *)usecase->stream;
2401 struct pcm_device *pcm_device;
2402 struct pcm_device_profile *pcm_profile;
2403 struct mixer_card *mixer_card;
2404 audio_devices_t devices = usecase->devices;
2405
2406 list_init(&usecase->mixer_list);
2407 list_init(&out->pcm_dev_list);
2408
2409 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2410 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002411 if (pcm_device == NULL) {
2412 return -ENOMEM;
2413 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002414 pcm_device->pcm_profile = pcm_profile;
2415 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2416 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2417 if (mixer_card == NULL) {
2418 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2419 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2420 }
2421 devices &= ~pcm_profile->devices;
2422 }
2423
2424 return 0;
2425}
2426
2427static int out_close_pcm_devices(struct stream_out *out)
2428{
2429 struct pcm_device *pcm_device;
2430 struct listnode *node;
2431 struct audio_device *adev = out->dev;
2432
2433 list_for_each(node, &out->pcm_dev_list) {
2434 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2435 if (pcm_device->sound_trigger_handle > 0) {
2436 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2437 pcm_device->sound_trigger_handle = 0;
2438 }
2439 if (pcm_device->pcm) {
2440 pcm_close(pcm_device->pcm);
2441 pcm_device->pcm = NULL;
2442 }
2443 if (pcm_device->resampler) {
2444 release_resampler(pcm_device->resampler);
2445 pcm_device->resampler = NULL;
2446 }
2447 if (pcm_device->res_buffer) {
2448 free(pcm_device->res_buffer);
2449 pcm_device->res_buffer = NULL;
2450 }
2451 }
2452
2453 return 0;
2454}
2455
2456static int out_open_pcm_devices(struct stream_out *out)
2457{
2458 struct pcm_device *pcm_device;
2459 struct listnode *node;
2460 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002461 int pcm_device_card;
2462 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002463
2464 list_for_each(node, &out->pcm_dev_list) {
2465 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002466 pcm_device_card = pcm_device->pcm_profile->card;
2467 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002468
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002469 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2470 pcm_device_id = pcm_device_deep_buffer.id;
2471
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002472 if (out->dev->voice.in_call) {
2473 ALOGV("%s: in_call, not opening PCMs", __func__);
2474 return ret;
2475 }
2476
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002477 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2478 __func__, pcm_device_card, pcm_device_id);
2479
2480 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002481 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2482
2483 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2484 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2485 pcm_device->pcm = NULL;
2486 ret = -EIO;
2487 goto error_open;
2488 }
2489 /*
2490 * If the stream rate differs from the PCM rate, we need to
2491 * create a resampler.
2492 */
2493 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2494 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2495 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002496 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002497 out->sample_rate, pcm_device->pcm_profile->config.rate);
2498 ret = create_resampler(out->sample_rate,
2499 pcm_device->pcm_profile->config.rate,
2500 audio_channel_count_from_out_mask(out->channel_mask),
2501 RESAMPLER_QUALITY_DEFAULT,
2502 NULL,
2503 &pcm_device->resampler);
2504 pcm_device->res_byte_count = 0;
2505 pcm_device->res_buffer = NULL;
2506 }
2507 }
2508 return ret;
2509
2510error_open:
2511 out_close_pcm_devices(out);
2512 return ret;
2513}
2514
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002515int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002516{
2517 struct audio_device *adev = out->dev;
2518 struct audio_usecase *uc_info;
2519
2520 uc_info = get_usecase_from_id(adev, out->usecase);
2521 if (uc_info == NULL) {
2522 ALOGE("%s: Could not find the usecase (%d) in the list",
2523 __func__, out->usecase);
2524 return -EINVAL;
2525 }
2526 disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
2527 uc_release_pcm_devices(uc_info);
2528 list_remove(&uc_info->adev_list_node);
2529 free(uc_info);
2530
2531 return 0;
2532}
2533
Andreas Schneider56204f62017-01-31 08:17:32 +01002534int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002535{
2536 struct audio_device *adev = out->dev;
2537 struct audio_usecase *uc_info;
2538
2539 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002540 if (uc_info == NULL) {
2541 return -ENOMEM;
2542 }
2543
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002544 uc_info->id = out->usecase;
2545 uc_info->type = PCM_PLAYBACK;
2546 uc_info->stream = (struct audio_stream *)out;
2547 uc_info->devices = out->devices;
2548 uc_info->in_snd_device = SND_DEVICE_NONE;
2549 uc_info->out_snd_device = SND_DEVICE_NONE;
2550 uc_select_pcm_devices(uc_info);
2551
2552 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2553 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002554
2555 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002556}
2557
2558static int stop_output_stream(struct stream_out *out)
2559{
2560 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002561 bool do_disable = true;
2562
2563 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2564 out->usecase, use_case_table[out->usecase]);
2565
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002566 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002567
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002568 if (do_disable)
2569 ret = disable_output_path_l(out);
2570
2571 ALOGV("%s: exit: status(%d)", __func__, ret);
2572 return ret;
2573}
2574
2575static int start_output_stream(struct stream_out *out)
2576{
2577 int ret = 0;
2578 struct audio_device *adev = out->dev;
2579
2580 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2581 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2582
Andreas Schneider56204f62017-01-31 08:17:32 +01002583 ret = enable_output_path_l(out);
2584 if (ret != 0) {
2585 goto error_config;
2586 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002587
2588 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2589 out->compr = NULL;
2590 ret = out_open_pcm_devices(out);
2591 if (ret != 0)
2592 goto error_open;
2593#ifdef PREPROCESSING_ENABLED
2594 out->echo_reference = NULL;
2595 out->echo_reference_generation = adev->echo_reference_generation;
2596 if (adev->echo_reference != NULL)
2597 out->echo_reference = adev->echo_reference;
2598#endif
2599 } else {
2600 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2601 COMPRESS_IN, &out->compr_config);
2602 if (out->compr && !is_compress_ready(out->compr)) {
2603 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2604 compress_close(out->compr);
2605 out->compr = NULL;
2606 ret = -EIO;
2607 goto error_open;
2608 }
2609 if (out->offload_callback)
2610 compress_nonblock(out->compr, out->non_blocking);
2611
2612 if (adev->offload_fx_start_output != NULL)
2613 adev->offload_fx_start_output(out->handle);
2614 }
2615 ALOGV("%s: exit", __func__);
2616 return 0;
2617error_open:
2618 stop_output_stream(out);
2619error_config:
2620 return ret;
2621}
2622
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002623int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002624{
2625 struct audio_usecase *uc_info;
2626
2627 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002628 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002629
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002630 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002631
2632 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2633 if (uc_info == NULL) {
2634 ALOGE("%s: Could not find the usecase (%d) in the list",
2635 __func__, USECASE_VOICE_CALL);
2636 return -EINVAL;
2637 }
2638
2639 disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
2640 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2641
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002642 list_remove(&uc_info->adev_list_node);
2643 free(uc_info);
2644
2645 ALOGV("%s: exit", __func__);
2646 return 0;
2647}
2648
2649/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002650int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002651{
2652 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002653 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002654
2655 ALOGV("%s: enter", __func__);
2656
2657 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002658 if (uc_info == NULL) {
2659 ret = -ENOMEM;
2660 goto exit;
2661 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002662 /*
2663 * We set this early so that functions called after this is being set
2664 * can use it. It is e.g. needed in select_devices() to inform the RILD
2665 * which output device we use.
2666 */
2667 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002668
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002669 uc_info->id = USECASE_VOICE_CALL;
2670 uc_info->type = VOICE_CALL;
2671 uc_info->stream = (struct audio_stream *)adev->primary_output;
2672 uc_info->devices = adev->primary_output->devices;
2673 uc_info->in_snd_device = SND_DEVICE_NONE;
2674 uc_info->out_snd_device = SND_DEVICE_NONE;
2675
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002676 list_init(&uc_info->mixer_list);
2677 list_add_tail(&uc_info->mixer_list,
2678 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002679
2680 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2681
2682 select_devices(adev, USECASE_VOICE_CALL);
2683
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002684 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002685
2686 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002687 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002688
Andreas Schneider56204f62017-01-31 08:17:32 +01002689exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002690 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002691 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002692}
2693
2694static int check_input_parameters(uint32_t sample_rate,
2695 audio_format_t format,
2696 int channel_count)
2697{
2698 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2699
2700 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2701
2702 switch (sample_rate) {
2703 case 8000:
2704 case 11025:
2705 case 12000:
2706 case 16000:
2707 case 22050:
2708 case 24000:
2709 case 32000:
2710 case 44100:
2711 case 48000:
2712 break;
2713 default:
2714 return -EINVAL;
2715 }
2716
2717 return 0;
2718}
2719
2720static size_t get_input_buffer_size(uint32_t sample_rate,
2721 audio_format_t format,
2722 int channel_count,
2723 usecase_type_t usecase_type,
2724 audio_devices_t devices)
2725{
2726 size_t size = 0;
2727 struct pcm_device_profile *pcm_profile;
2728
2729 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2730 return 0;
2731
2732 pcm_profile = get_pcm_device(usecase_type, devices);
2733 if (pcm_profile == NULL)
2734 return 0;
2735
2736 /*
2737 * take resampling into account and return the closest majoring
2738 * multiple of 16 frames, as audioflinger expects audio buffers to
2739 * be a multiple of 16 frames
2740 */
2741 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2742 size = ((size + 15) / 16) * 16;
2743
2744 return (size * channel_count * audio_bytes_per_sample(format));
2745
2746}
2747
2748static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2749{
2750 struct stream_out *out = (struct stream_out *)stream;
2751
2752 return out->sample_rate;
2753}
2754
2755static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2756{
2757 (void)stream;
2758 (void)rate;
2759 return -ENOSYS;
2760}
2761
2762static size_t out_get_buffer_size(const struct audio_stream *stream)
2763{
2764 struct stream_out *out = (struct stream_out *)stream;
2765
2766 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2767 return out->compr_config.fragment_size;
2768 }
2769
2770 return out->config.period_size *
2771 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2772}
2773
2774static uint32_t out_get_channels(const struct audio_stream *stream)
2775{
2776 struct stream_out *out = (struct stream_out *)stream;
2777
2778 return out->channel_mask;
2779}
2780
2781static audio_format_t out_get_format(const struct audio_stream *stream)
2782{
2783 struct stream_out *out = (struct stream_out *)stream;
2784
2785 return out->format;
2786}
2787
2788static int out_set_format(struct audio_stream *stream, audio_format_t format)
2789{
2790 (void)stream;
2791 (void)format;
2792 return -ENOSYS;
2793}
2794
2795static int do_out_standby_l(struct stream_out *out)
2796{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002797 int status = 0;
2798
2799 out->standby = true;
2800 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2801 out_close_pcm_devices(out);
2802#ifdef PREPROCESSING_ENABLED
2803 /* stop writing to echo reference */
2804 if (out->echo_reference != NULL) {
2805 out->echo_reference->write(out->echo_reference, NULL);
2806 if (out->echo_reference_generation != adev->echo_reference_generation) {
2807 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2808 release_echo_reference(out->echo_reference);
2809 out->echo_reference_generation = adev->echo_reference_generation;
2810 }
2811 out->echo_reference = NULL;
2812 }
2813#endif
2814 } else {
2815 stop_compressed_output_l(out);
2816 out->gapless_mdata.encoder_delay = 0;
2817 out->gapless_mdata.encoder_padding = 0;
2818 if (out->compr != NULL) {
2819 compress_close(out->compr);
2820 out->compr = NULL;
2821 }
2822 }
2823 status = stop_output_stream(out);
2824
2825 return status;
2826}
2827
2828static int out_standby(struct audio_stream *stream)
2829{
2830 struct stream_out *out = (struct stream_out *)stream;
2831 struct audio_device *adev = out->dev;
2832
2833 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2834 out->usecase, use_case_table[out->usecase]);
2835 lock_output_stream(out);
2836 if (!out->standby) {
2837 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002838 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002839 do_out_standby_l(out);
2840 pthread_mutex_unlock(&adev->lock);
2841 }
2842 pthread_mutex_unlock(&out->lock);
2843 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002844
2845 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2846
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002847 return 0;
2848}
2849
2850static int out_dump(const struct audio_stream *stream, int fd)
2851{
2852 (void)stream;
2853 (void)fd;
2854
2855 return 0;
2856}
2857
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002858static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2859{
2860 struct stream_out *out = (struct stream_out *)stream;
2861 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002862 struct listnode *node;
2863 struct str_parms *parms;
2864 char value[32];
2865 int ret, val = 0;
2866 struct audio_usecase *uc_info;
2867 bool do_standby = false;
2868 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002869#ifdef PREPROCESSING_ENABLED
2870 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2871#endif
2872
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002873 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2874 "adev->mode(%#x)",
2875 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2876 out->devices, adev->mode);
2877
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002878 parms = str_parms_create_str(kvpairs);
2879 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2880 if (ret >= 0) {
2881 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002882
2883 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2884 __func__, out->usecase, use_case_table[out->usecase], val,
2885 adev->mode);
2886
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002887 pthread_mutex_lock(&adev->lock_inputs);
2888 lock_output_stream(out);
2889 pthread_mutex_lock(&adev->lock);
2890#ifdef PREPROCESSING_ENABLED
2891 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2892 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2893 /* reset active input:
2894 * - to attach the echo reference
2895 * - because a change in output device may change mic settings */
2896 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2897 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2898 in = adev->active_input;
2899 }
2900 }
2901#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002902 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002903 bool bt_sco_active = false;
2904
2905 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2906 bt_sco_active = true;
2907 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002908 out->devices = val;
2909
2910 if (!out->standby) {
2911 uc_info = get_usecase_from_id(adev, out->usecase);
2912 if (uc_info == NULL) {
2913 ALOGE("%s: Could not find the usecase (%d) in the list",
2914 __func__, out->usecase);
2915 } else {
2916 list_for_each(node, &out->pcm_dev_list) {
2917 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2918 if ((pcm_device->pcm_profile->devices & val) == 0)
2919 do_standby = true;
2920 val &= ~pcm_device->pcm_profile->devices;
2921 }
2922 if (val != 0)
2923 do_standby = true;
2924 }
2925 if (do_standby)
2926 do_out_standby_l(out);
2927 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002928 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2929 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002930 select_devices(adev, out->usecase);
2931 }
2932 }
2933
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002934 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002935 (out == adev->primary_output)) {
2936 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002937 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2938 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002939 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002940 /* Turn on bluetooth if needed */
2941 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002942 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002943 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002944 } else {
2945 /*
2946 * When we select different devices we need to restart the
2947 * voice call. The modem closes the stream on its end and
2948 * we do not get any output.
2949 */
2950 stop_voice_call(adev);
2951 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002952 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002953 }
2954 }
2955
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002956 pthread_mutex_unlock(&adev->lock);
2957 pthread_mutex_unlock(&out->lock);
2958#ifdef PREPROCESSING_ENABLED
2959 if (in) {
2960 /* The lock on adev->lock_inputs prevents input stream from being closed */
2961 lock_input_stream(in);
2962 pthread_mutex_lock(&adev->lock);
2963 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2964 do_in_standby_l(in);
2965 pthread_mutex_unlock(&adev->lock);
2966 pthread_mutex_unlock(&in->lock);
2967 }
2968#endif
2969 pthread_mutex_unlock(&adev->lock_inputs);
2970 }
2971
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002972 amplifier_set_parameters(parms);
2973
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002974 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2975 parse_compress_metadata(out, parms);
2976 }
2977
2978 str_parms_destroy(parms);
2979
2980 if (ret > 0)
2981 ret = 0;
2982 ALOGV("%s: exit: code(%d)", __func__, ret);
2983 return ret;
2984}
2985
2986static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2987{
2988 struct stream_out *out = (struct stream_out *)stream;
2989 struct str_parms *query = str_parms_create_str(keys);
2990 char *str;
2991 char value[256];
2992 struct str_parms *reply = str_parms_create();
2993 size_t i, j;
2994 int ret;
2995 bool first = true;
2996 ALOGV("%s: enter: keys - %s", __func__, keys);
2997 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2998 if (ret >= 0) {
2999 value[0] = '\0';
3000 i = 0;
3001 while (out->supported_channel_masks[i] != 0) {
3002 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
3003 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
3004 if (!first) {
3005 strcat(value, "|");
3006 }
3007 strcat(value, out_channels_name_to_enum_table[j].name);
3008 first = false;
3009 break;
3010 }
3011 }
3012 i++;
3013 }
3014 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
3015 str = str_parms_to_str(reply);
3016 } else {
3017 str = strdup(keys);
3018 }
3019 str_parms_destroy(query);
3020 str_parms_destroy(reply);
3021 ALOGV("%s: exit: returns - %s", __func__, str);
3022 return str;
3023}
3024
3025static uint32_t out_get_latency(const struct audio_stream_out *stream)
3026{
3027 struct stream_out *out = (struct stream_out *)stream;
3028
3029 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3030 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
3031
3032 return (out->config.period_count * out->config.period_size * 1000) /
3033 (out->config.rate);
3034}
3035
3036static int out_set_volume(struct audio_stream_out *stream, float left,
3037 float right)
3038{
3039 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003040
3041 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
3042 /* only take left channel into account: the API is for stereo anyway */
3043 out->muted = (left == 0.0f);
3044 return 0;
3045 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003046 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003047 }
3048
3049 return -ENOSYS;
3050}
3051
Andreas Schneider3b643832017-01-31 11:48:22 +01003052#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003053static int fast_set_affinity(pid_t tid) {
3054 cpu_set_t cpu_set;
3055 int cpu_num;
3056 const char *irq_procfs = "/proc/asound/irq_affinity";
3057 FILE *fp;
3058
3059 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3060 ALOGW("Procfs node %s not found", irq_procfs);
3061 return -1;
3062 }
3063
3064 if (fscanf(fp, "%d", &cpu_num) != 1) {
3065 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3066 fclose(fp);
3067 return -1;
3068 }
3069 fclose(fp);
3070
3071 CPU_ZERO(&cpu_set);
3072 CPU_SET(cpu_num, &cpu_set);
3073 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3074}
Andreas Schneider3b643832017-01-31 11:48:22 +01003075#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003076
3077static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3078 size_t bytes)
3079{
3080 struct stream_out *out = (struct stream_out *)stream;
3081 struct audio_device *adev = out->dev;
3082 ssize_t ret = 0;
3083 struct pcm_device *pcm_device;
3084 struct listnode *node;
3085 size_t frame_size = audio_stream_out_frame_size(stream);
3086 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003087#ifdef PREPROCESSING_ENABLED
3088 size_t in_frames = bytes / frame_size;
3089 size_t out_frames = in_frames;
3090 struct stream_in *in = NULL;
3091#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003092
3093 lock_output_stream(out);
3094
Andreas Schneider3b643832017-01-31 11:48:22 +01003095#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003096 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003097 pid_t tid = gettid();
3098 int err;
3099
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003100 err = fast_set_affinity(tid);
3101 if (err < 0) {
3102 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3103 }
3104 out->is_fastmixer_affinity_set = true;
3105 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003106#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003107
3108 if (out->standby) {
3109#ifdef PREPROCESSING_ENABLED
3110 pthread_mutex_unlock(&out->lock);
3111 /* Prevent input stream from being closed */
3112 pthread_mutex_lock(&adev->lock_inputs);
3113 lock_output_stream(out);
3114 if (!out->standby) {
3115 pthread_mutex_unlock(&adev->lock_inputs);
3116 goto false_alarm;
3117 }
3118#endif
3119 pthread_mutex_lock(&adev->lock);
3120 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003121 if (ret == 0) {
3122 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3123 }
3124
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003125 /* ToDo: If use case is compress offload should return 0 */
3126 if (ret != 0) {
3127 pthread_mutex_unlock(&adev->lock);
3128#ifdef PREPROCESSING_ENABLED
3129 pthread_mutex_unlock(&adev->lock_inputs);
3130#endif
3131 goto exit;
3132 }
3133 out->standby = false;
3134
3135#ifdef PREPROCESSING_ENABLED
3136 /* A change in output device may change the microphone selection */
3137 if (adev->active_input &&
3138 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3139 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3140 in = adev->active_input;
3141 ALOGV("%s: enter:) force_input_standby true", __func__);
3142 }
3143#endif
3144 pthread_mutex_unlock(&adev->lock);
3145#ifdef PREPROCESSING_ENABLED
3146 if (!in) {
3147 /* Leave mutex locked iff in != NULL */
3148 pthread_mutex_unlock(&adev->lock_inputs);
3149 }
3150#endif
3151 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003152#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003153false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003154#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003155
3156 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003157 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003158 return ret;
3159 } else {
3160#ifdef PREPROCESSING_ENABLED
3161 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3162 != out->echo_reference_generation) {
3163 pthread_mutex_lock(&adev->lock);
3164 if (out->echo_reference != NULL) {
3165 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3166 release_echo_reference(out->echo_reference);
3167 }
3168 // note that adev->echo_reference_generation here can be different from the one
3169 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3170 // with what has been set by get_echo_reference() or put_echo_reference()
3171 out->echo_reference_generation = adev->echo_reference_generation;
3172 out->echo_reference = adev->echo_reference;
3173 ALOGV("%s: update echo reference generation %d", __func__,
3174 out->echo_reference_generation);
3175 pthread_mutex_unlock(&adev->lock);
3176 }
3177#endif
3178
3179 if (out->muted)
3180 memset((void *)buffer, 0, bytes);
3181 list_for_each(node, &out->pcm_dev_list) {
3182 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3183 if (pcm_device->resampler) {
3184 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3185 > pcm_device->res_byte_count) {
3186 pcm_device->res_byte_count =
3187 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3188 pcm_device->res_buffer =
3189 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3190 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3191 pcm_device->res_byte_count);
3192 }
3193 frames_rq = bytes / frame_size;
3194 frames_wr = pcm_device->res_byte_count / frame_size;
3195 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3196 __func__, frames_rq, frame_size);
3197 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3198 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3199 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3200 }
3201 if (pcm_device->pcm) {
3202#ifdef PREPROCESSING_ENABLED
3203 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3204 struct echo_reference_buffer b;
3205 b.raw = (void *)buffer;
3206 b.frame_count = in_frames;
3207
3208 get_playback_delay(out, out_frames, &b);
3209 out->echo_reference->write(out->echo_reference, &b);
3210 }
3211#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003212 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3213 if (pcm_device->resampler && pcm_device->res_buffer)
3214 pcm_device->status =
3215 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3216 frames_wr * frame_size);
3217 else
3218 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3219 if (pcm_device->status != 0)
3220 ret = pcm_device->status;
3221 }
3222 }
3223 if (ret == 0)
3224 out->written += bytes / (out->config.channels * sizeof(short));
3225 }
3226
3227exit:
3228 pthread_mutex_unlock(&out->lock);
3229
3230 if (ret != 0) {
3231 list_for_each(node, &out->pcm_dev_list) {
3232 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3233 if (pcm_device->pcm && pcm_device->status != 0)
3234 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3235 }
3236 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003237 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3238 clock_gettime(CLOCK_MONOTONIC, &t);
3239 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3240 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3241 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3242 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3243 if (sleep_time > 0) {
3244 usleep(sleep_time);
3245 } else {
3246 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3247 sleep_time = 0;
3248 }
3249 out->last_write_time_us = now + sleep_time;
3250 // last_write_time_us is an approximation of when the (simulated) alsa
3251 // buffer is believed completely full. The usleep above waits for more space
3252 // in the buffer, but by the end of the sleep the buffer is considered
3253 // topped-off.
3254 //
3255 // On the subsequent out_write(), we measure the elapsed time spent in
3256 // the mixer. This is subtracted from the sleep estimate based on frames,
3257 // thereby accounting for drain in the alsa buffer during mixing.
3258 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003259 }
3260
3261#ifdef PREPROCESSING_ENABLED
3262 if (in) {
3263 /* The lock on adev->lock_inputs prevents input stream from being closed */
3264 lock_input_stream(in);
3265 pthread_mutex_lock(&adev->lock);
3266 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3267 do_in_standby_l(in);
3268 pthread_mutex_unlock(&adev->lock);
3269 pthread_mutex_unlock(&in->lock);
3270 /* This mutex was left locked iff in != NULL */
3271 pthread_mutex_unlock(&adev->lock_inputs);
3272 }
3273#endif
3274
3275 return bytes;
3276}
3277
3278static int out_get_render_position(const struct audio_stream_out *stream,
3279 uint32_t *dsp_frames)
3280{
3281 struct stream_out *out = (struct stream_out *)stream;
3282 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003283 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3284 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003285 } else
3286 return -EINVAL;
3287}
3288
3289static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3290{
3291 (void)stream;
3292 (void)effect;
3293 return 0;
3294}
3295
3296static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3297{
3298 (void)stream;
3299 (void)effect;
3300 return 0;
3301}
3302
3303static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3304 int64_t *timestamp)
3305{
3306 (void)stream;
3307 (void)timestamp;
3308 return -EINVAL;
3309}
3310
3311static int out_get_presentation_position(const struct audio_stream_out *stream,
3312 uint64_t *frames, struct timespec *timestamp)
3313{
3314 struct stream_out *out = (struct stream_out *)stream;
3315 int ret = -1;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003316
3317 lock_output_stream(out);
3318
3319 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003320 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003321 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003322 if (out->dev->voice.in_call) {
3323 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3324 ret = 0;
3325 goto done;
3326 }
3327
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003328 /* FIXME: which device to read from? */
3329 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003330 struct pcm_device *pcm_device;
3331 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003332 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003333
Andreas Schneiderd6359182017-02-08 16:58:22 +01003334 list_for_each(node, &out->pcm_dev_list) {
3335 pcm_device = node_to_item(node,
3336 struct pcm_device,
3337 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003338
Andreas Schneiderd6359182017-02-08 16:58:22 +01003339 if (pcm_device->pcm != NULL) {
3340 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3341 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3342 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3343 /* This adjustment accounts for buffering after app processor.
3344 It is based on estimated DSP latency per use case, rather than exact. */
3345 signed_frames -=
3346 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3347
3348 /* It would be unusual for this value to be negative, but check just in case ... */
3349 if (signed_frames >= 0) {
3350 *frames = signed_frames;
3351 ret = 0;
3352 goto done;
3353 }
3354 ret = -1;
3355 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003356 }
3357 }
3358 }
3359 }
3360
Andreas Schneiderd6359182017-02-08 16:58:22 +01003361done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003362 pthread_mutex_unlock(&out->lock);
3363
3364 return ret;
3365}
3366
3367static int out_set_callback(struct audio_stream_out *stream,
3368 stream_callback_t callback, void *cookie)
3369{
3370 struct stream_out *out = (struct stream_out *)stream;
3371
3372 ALOGV("%s", __func__);
3373 lock_output_stream(out);
3374 out->offload_callback = callback;
3375 out->offload_cookie = cookie;
3376 pthread_mutex_unlock(&out->lock);
3377 return 0;
3378}
3379
3380static int out_pause(struct audio_stream_out* stream)
3381{
3382 struct stream_out *out = (struct stream_out *)stream;
3383 int status = -ENOSYS;
3384 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003385 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3386 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003387 return status;
3388}
3389
3390static int out_resume(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_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003397 return status;
3398}
3399
3400static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
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_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003407 return status;
3408}
3409
3410static int out_flush(struct audio_stream_out* stream)
3411{
3412 struct stream_out *out = (struct stream_out *)stream;
3413 ALOGV("%s", __func__);
3414 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003415 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003416 }
3417 return -ENOSYS;
3418}
3419
3420/** audio_stream_in implementation **/
3421static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3422{
3423 struct stream_in *in = (struct stream_in *)stream;
3424
3425 return in->requested_rate;
3426}
3427
3428static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3429{
3430 (void)stream;
3431 (void)rate;
3432 return -ENOSYS;
3433}
3434
3435static uint32_t in_get_channels(const struct audio_stream *stream)
3436{
3437 struct stream_in *in = (struct stream_in *)stream;
3438
3439 return in->main_channels;
3440}
3441
3442static audio_format_t in_get_format(const struct audio_stream *stream)
3443{
3444 (void)stream;
3445 return AUDIO_FORMAT_PCM_16_BIT;
3446}
3447
3448static int in_set_format(struct audio_stream *stream, audio_format_t format)
3449{
3450 (void)stream;
3451 (void)format;
3452
3453 return -ENOSYS;
3454}
3455
3456static size_t in_get_buffer_size(const struct audio_stream *stream)
3457{
3458 struct stream_in *in = (struct stream_in *)stream;
3459
3460 return get_input_buffer_size(in->requested_rate,
3461 in_get_format(stream),
3462 audio_channel_count_from_in_mask(in->main_channels),
3463 in->usecase_type,
3464 in->devices);
3465}
3466
3467static int in_close_pcm_devices(struct stream_in *in)
3468{
3469 struct pcm_device *pcm_device;
3470 struct listnode *node;
3471 struct audio_device *adev = in->dev;
3472
3473 list_for_each(node, &in->pcm_dev_list) {
3474 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3475 if (pcm_device) {
3476 if (pcm_device->pcm)
3477 pcm_close(pcm_device->pcm);
3478 pcm_device->pcm = NULL;
3479 if (pcm_device->sound_trigger_handle > 0)
3480 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3481 pcm_device->sound_trigger_handle = 0;
3482 }
3483 }
3484 return 0;
3485}
3486
3487
3488/* must be called with stream and hw device mutex locked */
3489static int do_in_standby_l(struct stream_in *in)
3490{
3491 int status = 0;
3492
3493#ifdef PREPROCESSING_ENABLED
3494 struct audio_device *adev = in->dev;
3495#endif
3496 if (!in->standby) {
3497
3498 in_close_pcm_devices(in);
3499
3500#ifdef PREPROCESSING_ENABLED
3501 if (in->echo_reference != NULL) {
3502 /* stop reading from echo reference */
3503 in->echo_reference->read(in->echo_reference, NULL);
3504 put_echo_reference(adev, in->echo_reference);
3505 in->echo_reference = NULL;
3506 }
3507#ifdef HW_AEC_LOOPBACK
3508 if (in->hw_echo_reference)
3509 {
3510 if (in->hw_ref_buf) {
3511 free(in->hw_ref_buf);
3512 in->hw_ref_buf = NULL;
3513 }
3514 }
3515#endif // HW_AEC_LOOPBACK
3516#endif // PREPROCESSING_ENABLED
3517
3518 status = stop_input_stream(in);
3519
3520 if (in->read_buf) {
3521 free(in->read_buf);
3522 in->read_buf = NULL;
3523 }
3524
3525 in->standby = 1;
3526 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003527
3528 in->last_read_time_us = 0;
3529
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003530 return 0;
3531}
3532
3533// called with adev->lock_inputs locked
3534static int in_standby_l(struct stream_in *in)
3535{
3536 struct audio_device *adev = in->dev;
3537 int status = 0;
3538 lock_input_stream(in);
3539 if (!in->standby) {
3540 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003541 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003542 status = do_in_standby_l(in);
3543 pthread_mutex_unlock(&adev->lock);
3544 }
3545 pthread_mutex_unlock(&in->lock);
3546 return status;
3547}
3548
3549static int in_standby(struct audio_stream *stream)
3550{
3551 struct stream_in *in = (struct stream_in *)stream;
3552 struct audio_device *adev = in->dev;
3553 int status;
3554 ALOGV("%s: enter", __func__);
3555 pthread_mutex_lock(&adev->lock_inputs);
3556 status = in_standby_l(in);
3557 pthread_mutex_unlock(&adev->lock_inputs);
3558 ALOGV("%s: exit: status(%d)", __func__, status);
3559 return status;
3560}
3561
3562static int in_dump(const struct audio_stream *stream, int fd)
3563{
3564 (void)stream;
3565 (void)fd;
3566
3567 return 0;
3568}
3569
3570static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3571{
3572 struct stream_in *in = (struct stream_in *)stream;
3573 struct audio_device *adev = in->dev;
3574 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003575 char value[32];
3576 int ret, val = 0;
3577 struct audio_usecase *uc_info;
3578 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003579 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003580
3581 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3582 parms = str_parms_create_str(kvpairs);
3583
3584 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3585
3586 pthread_mutex_lock(&adev->lock_inputs);
3587 lock_input_stream(in);
3588 pthread_mutex_lock(&adev->lock);
3589 if (ret >= 0) {
3590 val = atoi(value);
3591 /* no audio source uses val == 0 */
3592 if (((int)in->source != val) && (val != 0)) {
3593 in->source = val;
3594 }
3595 }
3596
3597 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3598 if (ret >= 0) {
3599 val = atoi(value);
3600 if (((int)in->devices != val) && (val != 0)) {
3601 in->devices = val;
3602 /* If recording is in progress, change the tx device to new device */
3603 if (!in->standby) {
3604 uc_info = get_usecase_from_id(adev, in->usecase);
3605 if (uc_info == NULL) {
3606 ALOGE("%s: Could not find the usecase (%d) in the list",
3607 __func__, in->usecase);
3608 } else {
3609 if (list_empty(&in->pcm_dev_list))
3610 ALOGE("%s: pcm device list empty", __func__);
3611 else {
3612 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3613 struct pcm_device, stream_list_node);
3614 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3615 do_standby = true;
3616 }
3617 }
3618 }
3619 if (do_standby) {
3620 ret = do_in_standby_l(in);
3621 } else
3622 ret = select_devices(adev, in->usecase);
3623 }
3624 }
3625 }
3626 pthread_mutex_unlock(&adev->lock);
3627 pthread_mutex_unlock(&in->lock);
3628 pthread_mutex_unlock(&adev->lock_inputs);
3629 str_parms_destroy(parms);
3630
3631 if (ret > 0)
3632 ret = 0;
3633
3634 ALOGV("%s: exit: status(%d)", __func__, ret);
3635 return ret;
3636}
3637
3638static char* in_get_parameters(const struct audio_stream *stream,
3639 const char *keys)
3640{
3641 (void)stream;
3642 (void)keys;
3643
3644 return strdup("");
3645}
3646
3647static int in_set_gain(struct audio_stream_in *stream, float gain)
3648{
3649 (void)stream;
3650 (void)gain;
3651
3652 return 0;
3653}
3654
3655static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3656 size_t bytes)
3657{
3658 struct pcm_device *pcm_device;
3659 struct audio_device *adev = in->dev;
3660
3661 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3662 struct pcm_device, stream_list_node);
3663
3664 if (pcm_device->sound_trigger_handle > 0)
3665 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3666 else
3667 return 0;
3668}
3669
3670static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3671 size_t bytes)
3672{
3673 struct stream_in *in = (struct stream_in *)stream;
3674 struct audio_device *adev = in->dev;
3675 ssize_t frames = -1;
3676 int ret = -1;
3677 int read_and_process_successful = false;
3678
3679 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003680
3681 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3682 lock_input_stream(in);
3683
Andreas Schneider3b643832017-01-31 11:48:22 +01003684#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003685 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003686 pid_t tid = gettid();
3687 int err;
3688
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003689 err = fast_set_affinity(tid);
3690 if (err < 0) {
3691 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3692 }
3693 in->is_fastcapture_affinity_set = true;
3694 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003695#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003696
3697 if (in->standby) {
3698 pthread_mutex_unlock(&in->lock);
3699 pthread_mutex_lock(&adev->lock_inputs);
3700 lock_input_stream(in);
3701 if (!in->standby) {
3702 pthread_mutex_unlock(&adev->lock_inputs);
3703 goto false_alarm;
3704 }
3705 pthread_mutex_lock(&adev->lock);
3706 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003707 if (ret == 0) {
3708 amplifier_input_stream_start(stream);
3709 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003710 pthread_mutex_unlock(&adev->lock);
3711 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003712
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003713 if (ret != 0) {
3714 goto exit;
3715 }
3716 in->standby = 0;
3717 }
3718false_alarm:
3719
3720 if (!list_empty(&in->pcm_dev_list)) {
3721 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3722 bytes = read_bytes_from_dsp(in, buffer, bytes);
3723 if (bytes > 0)
3724 read_and_process_successful = true;
3725 } else {
3726 /*
3727 * Read PCM and:
3728 * - resample if needed
3729 * - process if pre-processors are attached
3730 * - discard unwanted channels
3731 */
3732 frames = read_and_process_frames(in, buffer, frames_rq);
3733 if (frames >= 0)
3734 read_and_process_successful = true;
3735 }
3736 }
3737
3738 /*
3739 * Instead of writing zeroes here, we could trust the hardware
3740 * to always provide zeroes when muted.
3741 */
3742 if (read_and_process_successful == true && adev->mic_mute)
3743 memset(buffer, 0, bytes);
3744
3745exit:
3746 pthread_mutex_unlock(&in->lock);
3747
3748 if (read_and_process_successful == false) {
3749 in_standby(&in->stream.common);
3750 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003751 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3752 clock_gettime(CLOCK_MONOTONIC, &t);
3753 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3754
3755 // we do a full sleep when exiting standby.
3756 const bool standby = in->last_read_time_us == 0;
3757 const int64_t elapsed_time_since_last_read = standby ?
3758 0 : now - in->last_read_time_us;
3759 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3760 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3761 if (sleep_time > 0) {
3762 usleep(sleep_time);
3763 } else {
3764 sleep_time = 0;
3765 }
3766 in->last_read_time_us = now + sleep_time;
3767 // last_read_time_us is an approximation of when the (simulated) alsa
3768 // buffer is drained by the read, and is empty.
3769 //
3770 // On the subsequent in_read(), we measure the elapsed time spent in
3771 // the recording thread. This is subtracted from the sleep estimate based on frames,
3772 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003773 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003774 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003775
3776 if (bytes > 0) {
3777 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3778 }
3779
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003780 return bytes;
3781}
3782
3783static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3784{
3785 (void)stream;
3786
3787 return 0;
3788}
3789
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003790static int in_get_capture_position(const struct audio_stream_in *stream,
3791 int64_t *frames, int64_t *time)
3792{
3793 if (stream == NULL || frames == NULL || time == NULL) {
3794 return -EINVAL;
3795 }
3796
3797 struct stream_in *in = (struct stream_in *)stream;
3798 struct pcm_device *pcm_device;
3799 int ret = -ENOSYS;
3800
3801 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3802 struct pcm_device, stream_list_node);
3803
3804 pthread_mutex_lock(&in->lock);
3805 if (pcm_device->pcm) {
3806 struct timespec timestamp;
3807 unsigned int avail;
3808 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3809 *frames = in->frames_read + avail;
3810 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3811 ret = 0;
3812 }
3813 }
3814
3815 pthread_mutex_unlock(&in->lock);
3816 return ret;
3817}
3818
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003819static int add_remove_audio_effect(const struct audio_stream *stream,
3820 effect_handle_t effect,
3821 bool enable)
3822{
3823 struct stream_in *in = (struct stream_in *)stream;
3824 struct audio_device *adev = in->dev;
3825 int status = 0;
3826 effect_descriptor_t desc;
3827#ifdef PREPROCESSING_ENABLED
3828 int i;
3829#endif
3830 status = (*effect)->get_descriptor(effect, &desc);
3831 if (status != 0)
3832 return status;
3833
3834 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3835
3836 pthread_mutex_lock(&adev->lock_inputs);
3837 lock_input_stream(in);
3838 pthread_mutex_lock(&in->dev->lock);
3839#ifndef PREPROCESSING_ENABLED
3840 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3841 in->enable_aec != enable &&
3842 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3843 in->enable_aec = enable;
3844 if (!in->standby)
3845 select_devices(in->dev, in->usecase);
3846 }
3847#else
3848 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3849 status = -ENOSYS;
3850 goto exit;
3851 }
3852 if ( enable == true ) {
3853 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3854 /* add the supported channel of the effect in the channel_configs */
3855 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3856 in->num_preprocessors ++;
3857 /* check compatibility between main channel supported and possible auxiliary channels */
3858 in_update_aux_channels(in, effect);//wesley crash
3859 in->aux_channels_changed = true;
3860 } else {
3861 /* if ( enable == false ) */
3862 if (in->num_preprocessors <= 0) {
3863 status = -ENOSYS;
3864 goto exit;
3865 }
3866 status = -EINVAL;
3867 for (i=0; i < in->num_preprocessors; i++) {
3868 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3869 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3870 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3871 in->preprocessors[i - 1].num_channel_configs =
3872 in->preprocessors[i].num_channel_configs;
3873 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3874 continue;
3875 }
3876 if ( in->preprocessors[i].effect_itfe == effect ) {
3877 ALOGV("add_remove_audio_effect found fx at index %d", i);
3878 free(in->preprocessors[i].channel_configs);
3879 status = 0;
3880 }
3881 }
3882 if (status != 0)
3883 goto exit;
3884 in->num_preprocessors--;
3885 /* if we remove one effect, at least the last proproc should be reset */
3886 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3887 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3888 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3889 in->aux_channels_changed = false;
3890 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3891 }
3892 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3893
3894 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3895 in->enable_aec = enable;
3896 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3897 if (!in->standby) {
3898 select_devices(in->dev, in->usecase);
3899 do_in_standby_l(in);
3900 }
3901 if (in->enable_aec == true) {
3902 in_configure_reverse(in);
3903 }
3904 }
3905exit:
3906#endif
3907 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3908 pthread_mutex_unlock(&in->dev->lock);
3909 pthread_mutex_unlock(&in->lock);
3910 pthread_mutex_unlock(&adev->lock_inputs);
3911 return status;
3912}
3913
3914static int in_add_audio_effect(const struct audio_stream *stream,
3915 effect_handle_t effect)
3916{
3917 ALOGV("%s: effect %p", __func__, effect);
3918 return add_remove_audio_effect(stream, effect, true);
3919}
3920
3921static int in_remove_audio_effect(const struct audio_stream *stream,
3922 effect_handle_t effect)
3923{
3924 ALOGV("%s: effect %p", __func__, effect);
3925 return add_remove_audio_effect(stream, effect, false);
3926}
3927
3928static int adev_open_output_stream(struct audio_hw_device *dev,
3929 audio_io_handle_t handle,
3930 audio_devices_t devices,
3931 audio_output_flags_t flags,
3932 struct audio_config *config,
3933 struct audio_stream_out **stream_out,
3934 const char *address __unused)
3935{
3936 struct audio_device *adev = (struct audio_device *)dev;
3937 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003938 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003939 struct pcm_device_profile *pcm_profile;
3940
3941 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3942 __func__, config->sample_rate, config->channel_mask, devices, flags);
3943 *stream_out = NULL;
3944 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003945 if (out == NULL) {
3946 ret = -ENOMEM;
3947 goto error_config;
3948 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003949
3950 if (devices == AUDIO_DEVICE_NONE)
3951 devices = AUDIO_DEVICE_OUT_SPEAKER;
3952
3953 out->flags = flags;
3954 out->devices = devices;
3955 out->dev = adev;
3956 out->format = config->format;
3957 out->sample_rate = config->sample_rate;
3958 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3959 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3960 out->handle = handle;
3961
3962 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3963 if (pcm_profile == NULL) {
3964 ret = -EINVAL;
3965 goto error_open;
3966 }
3967 out->config = pcm_profile->config;
3968
3969 /* Init use case and pcm_config */
3970 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3971 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3972 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3973 ALOGE("%s: Unsupported Offload information", __func__);
3974 ret = -EINVAL;
3975 goto error_open;
3976 }
3977 if (!is_supported_format(config->offload_info.format)) {
3978 ALOGE("%s: Unsupported audio format", __func__);
3979 ret = -EINVAL;
3980 goto error_open;
3981 }
3982
3983 out->compr_config.codec = (struct snd_codec *)
3984 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003985 if (out->compr_config.codec == NULL) {
3986 ret = -ENOMEM;
3987 goto error_open;
3988 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003989
3990 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3991 if (config->offload_info.channel_mask)
3992 out->channel_mask = config->offload_info.channel_mask;
3993 else if (config->channel_mask)
3994 out->channel_mask = config->channel_mask;
3995 out->format = config->offload_info.format;
3996 out->sample_rate = config->offload_info.sample_rate;
3997
3998 out->stream.set_callback = out_set_callback;
3999 out->stream.pause = out_pause;
4000 out->stream.resume = out_resume;
4001 out->stream.drain = out_drain;
4002 out->stream.flush = out_flush;
4003
4004 out->compr_config.codec->id =
4005 get_snd_codec_id(config->offload_info.format);
4006 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
4007 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
4008 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
4009 out->compr_config.codec->bit_rate =
4010 config->offload_info.bit_rate;
4011 out->compr_config.codec->ch_in =
4012 audio_channel_count_from_out_mask(config->channel_mask);
4013 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4014
4015 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4016 out->non_blocking = 1;
4017
4018 out->send_new_metadata = 1;
4019 create_offload_callback_thread(out);
4020 out->offload_state = OFFLOAD_STATE_IDLE;
4021
4022 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4023 __func__, config->offload_info.version,
4024 config->offload_info.bit_rate);
4025 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4026 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004027 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004028 out->sample_rate = out->config.rate;
4029 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4030 } else {
4031 out->usecase = USECASE_AUDIO_PLAYBACK;
4032 out->sample_rate = out->config.rate;
4033 }
4034
4035 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4036 if (adev->primary_output == NULL)
4037 adev->primary_output = out;
4038 else {
4039 ALOGE("%s: Primary output is already opened", __func__);
4040 ret = -EEXIST;
4041 goto error_open;
4042 }
4043 }
4044
4045 /* Check if this usecase is already existing */
4046 pthread_mutex_lock(&adev->lock);
4047 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4048 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4049 pthread_mutex_unlock(&adev->lock);
4050 ret = -EEXIST;
4051 goto error_open;
4052 }
4053 pthread_mutex_unlock(&adev->lock);
4054
4055 out->stream.common.get_sample_rate = out_get_sample_rate;
4056 out->stream.common.set_sample_rate = out_set_sample_rate;
4057 out->stream.common.get_buffer_size = out_get_buffer_size;
4058 out->stream.common.get_channels = out_get_channels;
4059 out->stream.common.get_format = out_get_format;
4060 out->stream.common.set_format = out_set_format;
4061 out->stream.common.standby = out_standby;
4062 out->stream.common.dump = out_dump;
4063 out->stream.common.set_parameters = out_set_parameters;
4064 out->stream.common.get_parameters = out_get_parameters;
4065 out->stream.common.add_audio_effect = out_add_audio_effect;
4066 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4067 out->stream.get_latency = out_get_latency;
4068 out->stream.set_volume = out_set_volume;
4069 out->stream.write = out_write;
4070 out->stream.get_render_position = out_get_render_position;
4071 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4072 out->stream.get_presentation_position = out_get_presentation_position;
4073
4074 out->standby = 1;
4075 /* out->muted = false; by calloc() */
4076 /* out->written = 0; by calloc() */
4077
4078 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4079 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4080 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4081
4082 config->format = out->stream.common.get_format(&out->stream.common);
4083 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4084 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4085
4086 out->is_fastmixer_affinity_set = false;
4087
4088 *stream_out = &out->stream;
4089 ALOGV("%s: exit", __func__);
4090 return 0;
4091
4092error_open:
4093 free(out);
4094 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004095error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004096 ALOGV("%s: exit: ret %d", __func__, ret);
4097 return ret;
4098}
4099
4100static void adev_close_output_stream(struct audio_hw_device *dev,
4101 struct audio_stream_out *stream)
4102{
4103 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004104 (void)dev;
4105
4106 ALOGV("%s: enter", __func__);
4107 out_standby(&stream->common);
4108 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4109 destroy_offload_callback_thread(out);
4110
4111 if (out->compr_config.codec != NULL)
4112 free(out->compr_config.codec);
4113 }
4114 pthread_cond_destroy(&out->cond);
4115 pthread_mutex_destroy(&out->lock);
4116 free(stream);
4117 ALOGV("%s: exit", __func__);
4118}
4119
4120static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4121{
4122 struct audio_device *adev = (struct audio_device *)dev;
4123 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004124 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004125#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004126 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004127#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004128 int ret;
4129
4130 ALOGV("%s: enter: %s", __func__, kvpairs);
4131
4132 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004133
Andreas Schneider05bc1882017-02-09 14:03:11 +01004134 /******************************************************
4135 *** BT SCO
4136 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004137 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4138 if (ret >= 0) {
4139 /* When set to false, HAL should disable EC and NS
4140 * But it is currently not supported.
4141 */
4142 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004143 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004144 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004145 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004146 }
4147
Andreas Schneider05bc1882017-02-09 14:03:11 +01004148 ret = str_parms_get_str(parms,
4149 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4150 value,
4151 sizeof(value));
4152 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01004153 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4154 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01004155 } else {
4156 adev->voice.bluetooth_wb = false;
4157 }
4158 }
4159
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004160 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4161 if (ret >= 0) {
4162 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4163 adev->screen_off = false;
4164 else
4165 adev->screen_off = true;
4166 }
4167
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004168#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004169 ret = str_parms_get_int(parms, "rotation", &val);
4170 if (ret >= 0) {
4171 bool reverse_speakers = false;
4172 switch(val) {
4173 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4174 relative to the user when the device is rotated 90deg from its default rotation. This
4175 assumption is device-specific, not platform-specific like this code. */
4176 case 270:
4177 reverse_speakers = true;
4178 break;
4179 case 0:
4180 case 90:
4181 case 180:
4182 break;
4183 default:
4184 ALOGE("%s: unexpected rotation of %d", __func__, val);
4185 }
4186 pthread_mutex_lock(&adev->lock);
4187 if (adev->speaker_lr_swap != reverse_speakers) {
4188 adev->speaker_lr_swap = reverse_speakers;
4189 /* only update the selected device if there is active pcm playback */
4190 struct audio_usecase *usecase;
4191 struct listnode *node;
4192 list_for_each(node, &adev->usecase_list) {
4193 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4194 if (usecase->type == PCM_PLAYBACK) {
4195 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004196 break;
4197 }
4198 }
4199 }
4200 pthread_mutex_unlock(&adev->lock);
4201 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004202#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004203
4204 str_parms_destroy(parms);
4205
4206 if (ret > 0)
4207 ret = 0;
4208
4209 ALOGV("%s: exit with code(%d)", __func__, ret);
4210 return ret;
4211}
4212
4213static char* adev_get_parameters(const struct audio_hw_device *dev,
4214 const char *keys)
4215{
4216 (void)dev;
4217 (void)keys;
4218
4219 return strdup("");
4220}
4221
4222static int adev_init_check(const struct audio_hw_device *dev)
4223{
4224 (void)dev;
4225
4226 return 0;
4227}
4228
4229static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4230{
4231 int ret = 0;
4232 struct audio_device *adev = (struct audio_device *)dev;
4233 pthread_mutex_lock(&adev->lock);
4234 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004235 adev->voice.volume = volume;
4236 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004237 pthread_mutex_unlock(&adev->lock);
4238 return ret;
4239}
4240
4241static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4242{
4243 (void)dev;
4244 (void)volume;
4245
4246 return -ENOSYS;
4247}
4248
4249static int adev_get_master_volume(struct audio_hw_device *dev,
4250 float *volume)
4251{
4252 (void)dev;
4253 (void)volume;
4254
4255 return -ENOSYS;
4256}
4257
4258static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4259{
4260 (void)dev;
4261 (void)muted;
4262
4263 return -ENOSYS;
4264}
4265
4266static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4267{
4268 (void)dev;
4269 (void)muted;
4270
4271 return -ENOSYS;
4272}
4273
4274static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4275{
4276 struct audio_device *adev = (struct audio_device *)dev;
4277
4278 pthread_mutex_lock(&adev->lock);
4279 if (adev->mode != mode) {
4280 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004281 if (amplifier_set_mode(mode) != 0) {
4282 ALOGE("Failed setting amplifier mode");
4283 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004284 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004285
4286 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4287 stop_voice_call(adev);
4288 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004289 }
4290 pthread_mutex_unlock(&adev->lock);
4291 return 0;
4292}
4293
4294static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4295{
4296 struct audio_device *adev = (struct audio_device *)dev;
4297 int err = 0;
4298
4299 pthread_mutex_lock(&adev->lock);
4300 adev->mic_mute = state;
4301
4302 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004303 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004304 }
4305
4306 pthread_mutex_unlock(&adev->lock);
4307 return err;
4308}
4309
4310static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4311{
4312 struct audio_device *adev = (struct audio_device *)dev;
4313
4314 *state = adev->mic_mute;
4315
4316 return 0;
4317}
4318
4319static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4320 const struct audio_config *config)
4321{
4322 (void)dev;
4323
4324 /* NOTE: we default to built in mic which may cause a mismatch between what we
4325 * report here and the actual buffer size
4326 */
4327 return get_input_buffer_size(config->sample_rate,
4328 config->format,
4329 audio_channel_count_from_in_mask(config->channel_mask),
4330 PCM_CAPTURE /* usecase_type */,
4331 AUDIO_DEVICE_IN_BUILTIN_MIC);
4332}
4333
4334static int adev_open_input_stream(struct audio_hw_device *dev,
4335 audio_io_handle_t handle __unused,
4336 audio_devices_t devices,
4337 struct audio_config *config,
4338 struct audio_stream_in **stream_in,
4339 audio_input_flags_t flags,
4340 const char *address __unused,
4341 audio_source_t source)
4342{
4343 struct audio_device *adev = (struct audio_device *)dev;
4344 struct stream_in *in;
4345 struct pcm_device_profile *pcm_profile;
4346
4347 ALOGV("%s: enter", __func__);
4348
4349 *stream_in = NULL;
4350 if (check_input_parameters(config->sample_rate, config->format,
4351 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4352 return -EINVAL;
4353
4354 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4355 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4356 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4357 pcm_profile = get_pcm_device(usecase_type, devices);
4358 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4359 // a low latency profile may not exist for that device, fall back
4360 // to regular capture. the MixerThread automatically changes
4361 // to non-fast capture based on the buffer size.
4362 flags &= ~AUDIO_INPUT_FLAG_FAST;
4363 usecase_type = PCM_CAPTURE;
4364 pcm_profile = get_pcm_device(usecase_type, devices);
4365 }
4366 if (pcm_profile == NULL)
4367 return -EINVAL;
4368
4369 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004370 if (in == NULL) {
4371 return -ENOMEM;
4372 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004373
4374 in->stream.common.get_sample_rate = in_get_sample_rate;
4375 in->stream.common.set_sample_rate = in_set_sample_rate;
4376 in->stream.common.get_buffer_size = in_get_buffer_size;
4377 in->stream.common.get_channels = in_get_channels;
4378 in->stream.common.get_format = in_get_format;
4379 in->stream.common.set_format = in_set_format;
4380 in->stream.common.standby = in_standby;
4381 in->stream.common.dump = in_dump;
4382 in->stream.common.set_parameters = in_set_parameters;
4383 in->stream.common.get_parameters = in_get_parameters;
4384 in->stream.common.add_audio_effect = in_add_audio_effect;
4385 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4386 in->stream.set_gain = in_set_gain;
4387 in->stream.read = in_read;
4388 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004389 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004390
4391 in->devices = devices;
4392 in->source = source;
4393 in->dev = adev;
4394 in->standby = 1;
4395 in->main_channels = config->channel_mask;
4396 in->requested_rate = config->sample_rate;
4397 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4398 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4399 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004400 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004401 /* HW codec is limited to default channels. No need to update with
4402 * requested channels */
4403 in->config = pcm_profile->config;
4404
4405 /* Update config params with the requested sample rate and channels */
4406 if (source == AUDIO_SOURCE_HOTWORD) {
4407 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4408 } else {
4409 in->usecase = USECASE_AUDIO_CAPTURE;
4410 }
4411 in->usecase_type = usecase_type;
4412
4413 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4414 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4415
4416 in->is_fastcapture_affinity_set = false;
4417
4418 *stream_in = &in->stream;
4419 ALOGV("%s: exit", __func__);
4420 return 0;
4421}
4422
4423static void adev_close_input_stream(struct audio_hw_device *dev,
4424 struct audio_stream_in *stream)
4425{
4426 struct audio_device *adev = (struct audio_device *)dev;
4427 struct stream_in *in = (struct stream_in*)stream;
4428 ALOGV("%s", __func__);
4429
4430 /* prevent concurrent out_set_parameters, or out_write from standby */
4431 pthread_mutex_lock(&adev->lock_inputs);
4432
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004433 if (in->read_buf) {
4434 free(in->read_buf);
4435 in->read_buf = NULL;
4436 }
4437
4438 if (in->resampler) {
4439 release_resampler(in->resampler);
4440 in->resampler = NULL;
4441 }
4442
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004443#ifdef PREPROCESSING_ENABLED
4444 int i;
4445
4446 for (i=0; i<in->num_preprocessors; i++) {
4447 free(in->preprocessors[i].channel_configs);
4448 }
4449
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004450 if (in->proc_buf_in) {
4451 free(in->proc_buf_in);
4452 in->proc_buf_in = NULL;
4453 }
4454
4455 if (in->proc_buf_out) {
4456 free(in->proc_buf_out);
4457 in->proc_buf_out = NULL;
4458 }
4459
4460 if (in->ref_buf) {
4461 free(in->ref_buf);
4462 in->ref_buf = NULL;
4463 }
4464
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004465#endif
4466
4467 in_standby_l(in);
4468 free(stream);
4469
4470 pthread_mutex_unlock(&adev->lock_inputs);
4471
4472 return;
4473}
4474
4475static int adev_dump(const audio_hw_device_t *device, int fd)
4476{
4477 (void)device;
4478 (void)fd;
4479
4480 return 0;
4481}
4482
4483static int adev_close(hw_device_t *device)
4484{
4485 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004486 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004487 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004488 if (audio_device_ref_count == 0) {
4489 if (amplifier_close() != 0) {
4490 ALOGE("Amplifier close failed");
4491 }
4492 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004493 free(adev->snd_dev_ref_cnt);
4494 free_mixer_list(adev);
4495 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004496
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004497 adev = NULL;
4498
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004499 return 0;
4500}
4501
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004502/* This returns true if the input parameter looks at all plausible as a low latency period size,
4503 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4504 * just that it _might_ work.
4505 */
4506static bool period_size_is_plausible_for_low_latency(int period_size)
4507{
4508 switch (period_size) {
4509 case 64:
4510 case 96:
4511 case 128:
4512 case 192:
4513 case 256:
4514 return true;
4515 default:
4516 return false;
4517 }
4518}
4519
4520static int adev_open(const hw_module_t *module, const char *name,
4521 hw_device_t **device)
4522{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004523 ALOGV("%s: enter", __func__);
4524 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4525
Andreas Schneider56204f62017-01-31 08:17:32 +01004526 *device = NULL;
4527
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004528 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004529 if (adev == NULL) {
4530 return -ENOMEM;
4531 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004532
4533 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4534 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4535 adev->device.common.module = (struct hw_module_t *)module;
4536 adev->device.common.close = adev_close;
4537
4538 adev->device.init_check = adev_init_check;
4539 adev->device.set_voice_volume = adev_set_voice_volume;
4540 adev->device.set_master_volume = adev_set_master_volume;
4541 adev->device.get_master_volume = adev_get_master_volume;
4542 adev->device.set_master_mute = adev_set_master_mute;
4543 adev->device.get_master_mute = adev_get_master_mute;
4544 adev->device.set_mode = adev_set_mode;
4545 adev->device.set_mic_mute = adev_set_mic_mute;
4546 adev->device.get_mic_mute = adev_get_mic_mute;
4547 adev->device.set_parameters = adev_set_parameters;
4548 adev->device.get_parameters = adev_get_parameters;
4549 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4550 adev->device.open_output_stream = adev_open_output_stream;
4551 adev->device.close_output_stream = adev_close_output_stream;
4552 adev->device.open_input_stream = adev_open_input_stream;
4553 adev->device.close_input_stream = adev_close_input_stream;
4554 adev->device.dump = adev_dump;
4555
4556 /* Set the default route before the PCM stream is opened */
4557 adev->mode = AUDIO_MODE_NORMAL;
4558 adev->active_input = NULL;
4559 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004560
4561 adev->voice.volume = 1.0f;
4562 adev->voice.bluetooth_nrec = true;
4563 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004564 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004565
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004566 /* adev->cur_hdmi_channels = 0; by calloc() */
4567 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004568 if (adev->snd_dev_ref_cnt == NULL) {
4569 free(adev);
4570 return -ENOMEM;
4571 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004572
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004573 adev->ns_in_voice_rec = false;
4574
4575 list_init(&adev->usecase_list);
4576
4577 if (mixer_init(adev) != 0) {
4578 free(adev->snd_dev_ref_cnt);
4579 free(adev);
4580 ALOGE("%s: Failed to init, aborting.", __func__);
4581 *device = NULL;
4582 return -EINVAL;
4583 }
4584
4585 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4586 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4587 if (adev->offload_fx_lib == NULL) {
4588 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4589 } else {
4590 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4591 adev->offload_fx_start_output =
4592 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4593 "visualizer_hal_start_output");
4594 adev->offload_fx_stop_output =
4595 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4596 "visualizer_hal_stop_output");
4597 }
4598 }
4599
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004600 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4601 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4602 if (adev->sound_trigger_lib == NULL) {
4603 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4604 } else {
4605 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4606 adev->sound_trigger_open_for_streaming =
4607 (int (*)(void))dlsym(adev->sound_trigger_lib,
4608 "sound_trigger_open_for_streaming");
4609 adev->sound_trigger_read_samples =
4610 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4611 "sound_trigger_read_samples");
4612 adev->sound_trigger_close_for_streaming =
4613 (int (*)(int))dlsym(adev->sound_trigger_lib,
4614 "sound_trigger_close_for_streaming");
4615 if (!adev->sound_trigger_open_for_streaming ||
4616 !adev->sound_trigger_read_samples ||
4617 !adev->sound_trigger_close_for_streaming) {
4618
4619 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4620 adev->sound_trigger_open_for_streaming = 0;
4621 adev->sound_trigger_read_samples = 0;
4622 adev->sound_trigger_close_for_streaming = 0;
4623 }
4624 }
4625 }
4626
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004627 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004628 if (adev->voice.session == NULL) {
4629 ALOGE("%s: Failed to initialize voice session data", __func__);
4630
4631 free(adev->snd_dev_ref_cnt);
4632 free(adev);
4633
4634 *device = NULL;
4635 return -EINVAL;
4636 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004637
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004638 if (amplifier_open() != 0) {
4639 ALOGE("Amplifier initialization failed");
4640 }
4641
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004642 *device = &adev->device.common;
4643
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004644 audio_device_ref_count++;
4645
4646 char value[PROPERTY_VALUE_MAX];
4647 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4648 int trial = atoi(value);
4649 if (period_size_is_plausible_for_low_latency(trial)) {
4650
4651 pcm_device_playback.config.period_size = trial;
4652 pcm_device_playback.config.start_threshold =
4653 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4654 pcm_device_playback.config.stop_threshold =
4655 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4656
4657 pcm_device_capture_low_latency.config.period_size = trial;
4658 }
4659 }
4660
4661 ALOGV("%s: exit", __func__);
4662 return 0;
4663}
4664
4665static struct hw_module_methods_t hal_module_methods = {
4666 .open = adev_open,
4667};
4668
4669struct audio_module HAL_MODULE_INFO_SYM = {
4670 .common = {
4671 .tag = HARDWARE_MODULE_TAG,
4672 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4673 .hal_api_version = HARDWARE_HAL_API_VERSION,
4674 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004675 .name = "Samsung Audio HAL",
4676 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004677 .methods = &hal_module_methods,
4678 },
4679};