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