blob: cc9e622b353f9b9b717f51cc5459cd113ce8e403 [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 {
1063 in_snd_device = vc_usecase->in_snd_device;
1064 out_snd_device = vc_usecase->out_snd_device;
1065 }
1066 }
1067
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001068 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001069 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001070 prepare_voice_session(adev->voice.session, active_out->devices);
1071 out_snd_device = get_output_snd_device(adev, active_out->devices);
1072 in_snd_device = get_input_snd_device(adev, active_out->devices);
1073 } else if (usecase->type == PCM_PLAYBACK) {
1074 usecase->devices = active_out->devices;
1075 in_snd_device = SND_DEVICE_NONE;
1076 if (out_snd_device == SND_DEVICE_NONE) {
1077 out_snd_device = get_output_snd_device(adev, active_out->devices);
1078 if (active_out == adev->primary_output &&
1079 active_input &&
1080 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1081 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001082 }
1083 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001084 } else if (usecase->type == PCM_CAPTURE) {
1085 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1086 out_snd_device = SND_DEVICE_NONE;
1087 if (in_snd_device == SND_DEVICE_NONE) {
1088 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1089 adev->primary_output && !adev->primary_output->standby) {
1090 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1091 } else {
1092 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001093 }
1094 }
1095 }
1096
1097 if (out_snd_device == usecase->out_snd_device &&
1098 in_snd_device == usecase->in_snd_device) {
1099 return 0;
1100 }
1101
1102 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1103 out_snd_device, get_snd_device_display_name(out_snd_device),
1104 in_snd_device, get_snd_device_display_name(in_snd_device));
1105
1106
1107 /* Disable current sound devices */
1108 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001109 disable_snd_device(adev, usecase, usecase->out_snd_device, false);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001110 }
1111
1112 if (usecase->in_snd_device != SND_DEVICE_NONE) {
1113 disable_snd_device(adev, usecase, usecase->in_snd_device, false);
1114 }
1115
1116 /* Enable new sound devices */
1117 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001118 /* We need to update the audio path if we switch the out devices */
1119 if (adev->voice.in_call) {
1120 set_voice_session_audio_path(adev->voice.session);
1121 }
1122
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001123 enable_snd_device(adev, usecase, out_snd_device, false);
1124 }
1125
1126 if (in_snd_device != SND_DEVICE_NONE) {
1127 enable_snd_device(adev, usecase, in_snd_device, false);
1128 }
1129
1130 list_for_each(node, &usecase->mixer_list) {
1131 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
1132 audio_route_update_mixer(mixer_card->audio_route);
1133 }
1134
1135 usecase->in_snd_device = in_snd_device;
1136 usecase->out_snd_device = out_snd_device;
1137
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001138 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1139 amplifier_set_input_devices(in_snd_device);
1140 amplifier_set_output_devices(out_snd_device);
1141
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001142 return 0;
1143}
1144
1145
1146static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1147static int do_in_standby_l(struct stream_in *in);
1148
1149#ifdef PREPROCESSING_ENABLED
1150static void get_capture_reference_delay(struct stream_in *in,
1151 size_t frames __unused,
1152 struct echo_reference_buffer *buffer)
1153{
1154 ALOGVV("%s: enter:)", __func__);
1155
1156 /* read frames available in kernel driver buffer */
1157 unsigned int kernel_frames;
1158 struct timespec tstamp;
1159 long buf_delay;
1160 long kernel_delay;
1161 long delay_ns;
1162 struct pcm_device *ref_device;
1163 long rsmp_delay = 0;
1164
1165 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1166 struct pcm_device, stream_list_node);
1167
1168 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1169 buffer->time_stamp.tv_sec = 0;
1170 buffer->time_stamp.tv_nsec = 0;
1171 buffer->delay_ns = 0;
1172 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1173 return;
1174 }
1175
1176 /* adjust render time stamp with delay added by current driver buffer.
1177 * Add the duration of current frame as we want the render time of the last
1178 * sample being written. */
1179
1180 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1181
1182 buffer->time_stamp = tstamp;
1183 buffer->delay_ns = kernel_delay;
1184
1185 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1186 " delay_ns: [%d] , frames:[%zd]",
1187 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1188}
1189
1190static void get_capture_delay(struct stream_in *in,
1191 size_t frames __unused,
1192 struct echo_reference_buffer *buffer)
1193{
1194 ALOGVV("%s: enter:)", __func__);
1195 /* read frames available in kernel driver buffer */
1196 unsigned int kernel_frames;
1197 struct timespec tstamp;
1198 long buf_delay;
1199 long rsmp_delay;
1200 long kernel_delay;
1201 long delay_ns;
1202 struct pcm_device *pcm_device;
1203
1204 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1205 struct pcm_device, stream_list_node);
1206
1207 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1208 buffer->time_stamp.tv_sec = 0;
1209 buffer->time_stamp.tv_nsec = 0;
1210 buffer->delay_ns = 0;
1211 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1212 return;
1213 }
1214
1215 /* read frames available in audio HAL input buffer
1216 * add number of frames being read as we want the capture time of first sample
1217 * in current buffer */
1218 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1219 * at requested sampling rate */
1220 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1221 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1222
1223 /* add delay introduced by resampler */
1224 rsmp_delay = 0;
1225 if (in->resampler) {
1226 rsmp_delay = in->resampler->delay_ns(in->resampler);
1227 }
1228
1229 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1230
1231 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1232
1233 buffer->time_stamp = tstamp;
1234 buffer->delay_ns = delay_ns;
1235 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1236 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1237 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1238 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1239 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1240 in->read_buf_frames, in->proc_buf_frames, frames);
1241}
1242
1243static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1244{
1245 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1246 struct echo_reference_buffer b;
1247 b.delay_ns = 0;
1248 struct pcm_device *pcm_device;
1249
1250 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1251 struct pcm_device, stream_list_node);
1252
1253 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1254 "b.frame_count = [%zd]",
1255 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1256 if (in->ref_buf_frames < frames) {
1257 if (in->ref_buf_size < frames) {
1258 in->ref_buf_size = frames;
1259 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1260 ALOG_ASSERT((in->ref_buf != NULL),
1261 "update_echo_reference() failed to reallocate ref_buf");
1262 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1263 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1264 }
1265 b.frame_count = frames - in->ref_buf_frames;
1266 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1267
1268 get_capture_delay(in, frames, &b);
1269
1270 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1271 {
1272 in->ref_buf_frames += b.frame_count;
1273 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1274 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1275 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1276 }
1277 } else
1278 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1279 return b.delay_ns;
1280}
1281
1282static int set_preprocessor_param(effect_handle_t handle,
1283 effect_param_t *param)
1284{
1285 uint32_t size = sizeof(int);
1286 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1287 param->vsize;
1288
1289 int status = (*handle)->command(handle,
1290 EFFECT_CMD_SET_PARAM,
1291 sizeof (effect_param_t) + psize,
1292 param,
1293 &size,
1294 &param->status);
1295 if (status == 0)
1296 status = param->status;
1297
1298 return status;
1299}
1300
1301static int set_preprocessor_echo_delay(effect_handle_t handle,
1302 int32_t delay_us)
1303{
1304 struct {
1305 effect_param_t param;
1306 uint32_t data_0;
1307 int32_t data_1;
1308 } buf;
1309 memset(&buf, 0, sizeof(buf));
1310
1311 buf.param.psize = sizeof(uint32_t);
1312 buf.param.vsize = sizeof(uint32_t);
1313 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1314 buf.data_1 = delay_us;
1315
1316 return set_preprocessor_param(handle, &buf.param);
1317}
1318
1319static void push_echo_reference(struct stream_in *in, size_t frames)
1320{
1321 ALOGVV("%s: enter:)", __func__);
1322 /* read frames from echo reference buffer and update echo delay
1323 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1324
1325 int32_t delay_us = update_echo_reference(in, frames)/1000;
1326 int32_t size_in_bytes = 0;
1327 int i;
1328 audio_buffer_t buf;
1329
1330 if (in->ref_buf_frames < frames)
1331 frames = in->ref_buf_frames;
1332
1333 buf.frameCount = frames;
1334 buf.raw = in->ref_buf;
1335
1336 for (i = 0; i < in->num_preprocessors; i++) {
1337 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1338 continue;
1339 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1340 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1341 &buf,
1342 NULL);
1343 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1344 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1345 }
1346
1347 in->ref_buf_frames -= buf.frameCount;
1348 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1349 __func__, in->ref_buf_frames, in->config.channels);
1350 if (in->ref_buf_frames) {
1351 memcpy(in->ref_buf,
1352 in->ref_buf + buf.frameCount * in->config.channels,
1353 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1354 }
1355}
1356
1357static void put_echo_reference(struct audio_device *adev,
1358 struct echo_reference_itfe *reference)
1359{
1360 ALOGV("%s: enter:)", __func__);
1361 int32_t prev_generation = adev->echo_reference_generation;
1362 struct stream_out *out = adev->primary_output;
1363
1364 if (adev->echo_reference != NULL &&
1365 reference == adev->echo_reference) {
1366 /* echo reference is taken from the low latency output stream used
1367 * for voice use cases */
1368 adev->echo_reference = NULL;
1369 android_atomic_inc(&adev->echo_reference_generation);
1370 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1371 // if the primary output is in standby or did not pick the echo reference yet
1372 // we can safely get rid of it here.
1373 // otherwise, out_write() or out_standby() will detect the change in echo reference
1374 // generation and release the echo reference owned by the stream.
1375 if ((out->echo_reference_generation != prev_generation) || out->standby)
1376 release_echo_reference(reference);
1377 } else {
1378 release_echo_reference(reference);
1379 }
1380 ALOGV("release_echo_reference");
1381 }
1382}
1383
1384static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1385 audio_format_t format __unused,
1386 uint32_t channel_count,
1387 uint32_t sampling_rate)
1388{
1389 ALOGV("%s: enter:)", __func__);
1390 put_echo_reference(adev, adev->echo_reference);
1391 /* echo reference is taken from the low latency output stream used
1392 * for voice use cases */
1393 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1394 !adev->primary_output->standby) {
1395 struct audio_stream *stream =
1396 &adev->primary_output->stream.common;
1397 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1398 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1399 ALOGV("Calling create_echo_reference");
1400 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1401 channel_count,
1402 sampling_rate,
1403 AUDIO_FORMAT_PCM_16_BIT,
1404 wr_channel_count,
1405 wr_sampling_rate,
1406 &adev->echo_reference);
1407 if (status == 0)
1408 android_atomic_inc(&adev->echo_reference_generation);
1409 }
1410 return adev->echo_reference;
1411}
1412
1413#ifdef HW_AEC_LOOPBACK
1414static int get_hw_echo_reference(struct stream_in *in)
1415{
1416 struct pcm_device_profile *ref_pcm_profile;
1417 struct pcm_device *ref_device;
1418 struct audio_device *adev = in->dev;
1419
1420 in->hw_echo_reference = false;
1421
1422 if (adev->primary_output!= NULL &&
1423 !adev->primary_output->standby &&
1424 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1425 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1426 struct audio_stream *stream = &adev->primary_output->stream.common;
1427
1428 // TODO: currently there is no low latency mode for aec reference.
1429 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1430 if (ref_pcm_profile == NULL) {
1431 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1432 __func__, pcm_device_capture_loopback_aec.devices);
1433 return -EINVAL;
1434 }
1435
1436 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001437 if (ref_device == NULL) {
1438 return -ENOMEM;
1439 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001440 ref_device->pcm_profile = ref_pcm_profile;
1441
1442 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1443 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1444
1445 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1446 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1447 pcm_close(ref_device->pcm);
1448 ref_device->pcm = NULL;
1449 return -EIO;
1450 }
1451 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1452
1453 in->hw_echo_reference = true;
1454
1455 ALOGV("%s: hw_echo_reference is true", __func__);
1456 }
1457
1458 return 0;
1459}
1460#endif
1461
1462static int get_playback_delay(struct stream_out *out,
1463 size_t frames,
1464 struct echo_reference_buffer *buffer)
1465{
1466 unsigned int kernel_frames;
1467 int status;
1468 int primary_pcm = 0;
1469 struct pcm_device *pcm_device;
1470
1471 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1472 struct pcm_device, stream_list_node);
1473
1474 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1475 if (status < 0) {
1476 buffer->time_stamp.tv_sec = 0;
1477 buffer->time_stamp.tv_nsec = 0;
1478 buffer->delay_ns = 0;
1479 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1480 "setting playbackTimestamp to 0");
1481 return status;
1482 }
1483
1484 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1485
1486 /* adjust render time stamp with delay added by current driver buffer.
1487 * Add the duration of current frame as we want the render time of the last
1488 * sample being written. */
1489 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1490 out->config.rate);
1491 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1492 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1493
1494 return 0;
1495}
1496
1497#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1498 do { \
1499 if (fct_status != 0) \
1500 status = fct_status; \
1501 else if (cmd_status != 0) \
1502 status = cmd_status; \
1503 } while(0)
1504
1505static int in_configure_reverse(struct stream_in *in)
1506{
1507 int32_t cmd_status;
1508 uint32_t size = sizeof(int);
1509 effect_config_t config;
1510 int32_t status = 0;
1511 int32_t fct_status = 0;
1512 int i;
1513 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1514 if (in->num_preprocessors > 0) {
1515 config.inputCfg.channels = in->main_channels;
1516 config.outputCfg.channels = in->main_channels;
1517 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1518 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1519 config.inputCfg.samplingRate = in->requested_rate;
1520 config.outputCfg.samplingRate = in->requested_rate;
1521 config.inputCfg.mask =
1522 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1523 config.outputCfg.mask =
1524 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1525
1526 for (i = 0; i < in->num_preprocessors; i++)
1527 {
1528 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1529 continue;
1530 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1531 in->preprocessors[i].effect_itfe,
1532 EFFECT_CMD_SET_CONFIG_REVERSE,
1533 sizeof(effect_config_t),
1534 &config,
1535 &size,
1536 &cmd_status);
1537 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1538 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1539 }
1540 }
1541 return status;
1542}
1543
1544#define MAX_NUM_CHANNEL_CONFIGS 10
1545
1546static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1547 struct effect_info_s *effect_info)
1548{
1549 /* size and format of the cmd are defined in hardware/audio_effect.h */
1550 effect_handle_t effect = effect_info->effect_itfe;
1551 uint32_t cmd_size = 2 * sizeof(uint32_t);
1552 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1553 /* reply = status + number of configs (n) + n x channel_config_t */
1554 uint32_t reply_size =
1555 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1556 int32_t reply[reply_size];
1557 int32_t cmd_status;
1558
1559 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1560 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1561 ALOG_ASSERT((effect_info->channel_configs == NULL),
1562 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1563
1564 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1565 * This error will be interpreted as if the effect supports the main_channels but does not
1566 * support any aux_channels */
1567 cmd_status = (*effect)->command(effect,
1568 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1569 cmd_size,
1570 (void*)&cmd,
1571 &reply_size,
1572 (void*)&reply);
1573
1574 if (cmd_status != 0) {
1575 ALOGV("in_read_audio_effect_channel_configs(): "
1576 "fx->command returned %d", cmd_status);
1577 return;
1578 }
1579
1580 if (reply[0] != 0) {
1581 ALOGW("in_read_audio_effect_channel_configs(): "
1582 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1583 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1584 return;
1585 }
1586
1587 /* the feature is not supported */
1588 ALOGV("in_read_audio_effect_channel_configs()(): "
1589 "Feature supported and adding %d channel configs to the list", reply[1]);
1590 effect_info->num_channel_configs = reply[1];
1591 effect_info->channel_configs =
1592 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1593 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1594}
1595
1596
1597#define NUM_IN_AUX_CNL_CONFIGS 2
1598static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1599 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1600 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1601};
1602static uint32_t in_get_aux_channels(struct stream_in *in)
1603{
1604 int i;
1605 channel_config_t new_chcfg = {0, 0};
1606
1607 if (in->num_preprocessors == 0)
1608 return 0;
1609
1610 /* do not enable dual mic configurations when capturing from other microphones than
1611 * main or sub */
1612 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1613 return 0;
1614
1615 /* retain most complex aux channels configuration compatible with requested main channels and
1616 * supported by audio driver and all pre processors */
1617 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1618 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1619 if (cur_chcfg->main_channels == in->main_channels) {
1620 size_t match_cnt;
1621 size_t idx_preproc;
1622 for (idx_preproc = 0, match_cnt = 0;
1623 /* no need to continue if at least one preprocessor doesn't match */
1624 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1625 idx_preproc++) {
1626 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1627 size_t idx_chcfg;
1628
1629 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1630 if (memcmp(effect_info->channel_configs + idx_chcfg,
1631 cur_chcfg,
1632 sizeof(channel_config_t)) == 0) {
1633 match_cnt++;
1634 break;
1635 }
1636 }
1637 }
1638 /* if all preprocessors match, we have a candidate */
1639 if (match_cnt == (size_t)in->num_preprocessors) {
1640 /* retain most complex aux channels configuration */
1641 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1642 new_chcfg = *cur_chcfg;
1643 }
1644 }
1645 }
1646 }
1647
1648 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1649
1650 return new_chcfg.aux_channels;
1651}
1652
1653static int in_configure_effect_channels(effect_handle_t effect,
1654 channel_config_t *channel_config)
1655{
1656 int status = 0;
1657 int fct_status;
1658 int32_t cmd_status;
1659 uint32_t reply_size;
1660 effect_config_t config;
1661 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1662
1663 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1664 channel_config->main_channels,
1665 channel_config->aux_channels);
1666
1667 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1668 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1669 reply_size = sizeof(effect_config_t);
1670 fct_status = (*effect)->command(effect,
1671 EFFECT_CMD_GET_CONFIG,
1672 0,
1673 NULL,
1674 &reply_size,
1675 &config);
1676 if (fct_status != 0) {
1677 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1678 return fct_status;
1679 }
1680
1681 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1682 config.outputCfg.channels = config.inputCfg.channels;
1683 reply_size = sizeof(uint32_t);
1684 fct_status = (*effect)->command(effect,
1685 EFFECT_CMD_SET_CONFIG,
1686 sizeof(effect_config_t),
1687 &config,
1688 &reply_size,
1689 &cmd_status);
1690 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1691
1692 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1693 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1694 reply_size = sizeof(uint32_t);
1695 fct_status = (*effect)->command(effect,
1696 EFFECT_CMD_SET_FEATURE_CONFIG,
1697 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1698 cmd,
1699 &reply_size,
1700 &cmd_status);
1701 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1702
1703 /* some implementations need to be re-enabled after a config change */
1704 reply_size = sizeof(uint32_t);
1705 fct_status = (*effect)->command(effect,
1706 EFFECT_CMD_ENABLE,
1707 0,
1708 NULL,
1709 &reply_size,
1710 &cmd_status);
1711 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1712
1713 return status;
1714}
1715
1716static int in_reconfigure_channels(struct stream_in *in,
1717 effect_handle_t effect,
1718 channel_config_t *channel_config,
1719 bool config_changed) {
1720
1721 int status = 0;
1722
1723 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1724 config_changed, effect);
1725
1726 /* if config changed, reconfigure all previously added effects */
1727 if (config_changed) {
1728 int i;
1729 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1730 for (i = 0; i < in->num_preprocessors; i++)
1731 {
1732 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1733 channel_config);
1734 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1735 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1736 if (cur_status != 0) {
1737 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1738 "%d with channels: [%04x][%04x]",
1739 cur_status,
1740 i,
1741 channel_config->main_channels,
1742 channel_config->aux_channels);
1743 status = cur_status;
1744 }
1745 }
1746 } else if (effect != NULL && channel_config->aux_channels) {
1747 /* if aux channels config did not change but aux channels are present,
1748 * we still need to configure the effect being added */
1749 status = in_configure_effect_channels(effect, channel_config);
1750 }
1751 return status;
1752}
1753
1754static void in_update_aux_channels(struct stream_in *in,
1755 effect_handle_t effect)
1756{
1757 uint32_t aux_channels;
1758 channel_config_t channel_config;
1759 int status;
1760
1761 aux_channels = in_get_aux_channels(in);
1762
1763 channel_config.main_channels = in->main_channels;
1764 channel_config.aux_channels = aux_channels;
1765 status = in_reconfigure_channels(in,
1766 effect,
1767 &channel_config,
1768 (aux_channels != in->aux_channels));
1769
1770 if (status != 0) {
1771 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1772 /* resetting aux channels configuration */
1773 aux_channels = 0;
1774 channel_config.aux_channels = 0;
1775 in_reconfigure_channels(in, effect, &channel_config, true);
1776 }
1777 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1778 if (in->aux_channels != aux_channels) {
1779 in->aux_channels_changed = true;
1780 in->aux_channels = aux_channels;
1781 do_in_standby_l(in);
1782 }
1783}
1784#endif
1785
1786/* This function reads PCM data and:
1787 * - resample if needed
1788 * - process if pre-processors are attached
1789 * - discard unwanted channels
1790 */
1791static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1792{
1793 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001794 size_t src_channels = in->config.channels;
1795 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1796 int i;
1797 void *proc_buf_out;
1798 struct pcm_device *pcm_device;
1799 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1800#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001801 audio_buffer_t in_buf;
1802 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001803 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1804#endif
1805
1806 /* Additional channels might be added on top of main_channels:
1807 * - aux_channels (by processing effects)
1808 * - extra channels due to HW limitations
1809 * In case of additional channels, we cannot work inplace
1810 */
1811 if (has_additional_channels)
1812 proc_buf_out = in->proc_buf_out;
1813 else
1814 proc_buf_out = buffer;
1815
1816 if (list_empty(&in->pcm_dev_list)) {
1817 ALOGE("%s: pcm device list empty", __func__);
1818 return -EINVAL;
1819 }
1820
1821 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1822 struct pcm_device, stream_list_node);
1823
1824#ifdef PREPROCESSING_ENABLED
1825 if (has_processing) {
1826 /* since all the processing below is done in frames and using the config.channels
1827 * as the number of channels, no changes is required in case aux_channels are present */
1828 while (frames_wr < frames) {
1829 /* first reload enough frames at the end of process input buffer */
1830 if (in->proc_buf_frames < (size_t)frames) {
1831 ssize_t frames_rd;
1832 if (in->proc_buf_size < (size_t)frames) {
1833 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1834 in->proc_buf_size = (size_t)frames;
1835 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1836 ALOG_ASSERT((in->proc_buf_in != NULL),
1837 "process_frames() failed to reallocate proc_buf_in");
1838 if (has_additional_channels) {
1839 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1840 ALOG_ASSERT((in->proc_buf_out != NULL),
1841 "process_frames() failed to reallocate proc_buf_out");
1842 proc_buf_out = in->proc_buf_out;
1843 }
1844 }
1845 frames_rd = read_frames(in,
1846 in->proc_buf_in +
1847 in->proc_buf_frames * in->config.channels,
1848 frames - in->proc_buf_frames);
1849 if (frames_rd < 0) {
1850 /* Return error code */
1851 frames_wr = frames_rd;
1852 break;
1853 }
1854 in->proc_buf_frames += frames_rd;
1855 }
1856
1857 if (in->echo_reference != NULL) {
1858 push_echo_reference(in, in->proc_buf_frames);
1859 }
1860
1861 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1862 * the maximum number of frames to be consumed and produced by process() */
1863 in_buf.frameCount = in->proc_buf_frames;
1864 in_buf.s16 = in->proc_buf_in;
1865 out_buf.frameCount = frames - frames_wr;
1866 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1867
1868 /* FIXME: this works because of current pre processing library implementation that
1869 * does the actual process only when the last enabled effect process is called.
1870 * The generic solution is to have an output buffer for each effect and pass it as
1871 * input to the next.
1872 */
1873 for (i = 0; i < in->num_preprocessors; i++) {
1874 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1875 &in_buf,
1876 &out_buf);
1877 }
1878
1879 /* process() has updated the number of frames consumed and produced in
1880 * in_buf.frameCount and out_buf.frameCount respectively
1881 * move remaining frames to the beginning of in->proc_buf_in */
1882 in->proc_buf_frames -= in_buf.frameCount;
1883
1884 if (in->proc_buf_frames) {
1885 memcpy(in->proc_buf_in,
1886 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1887 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1888 }
1889
1890 /* if not enough frames were passed to process(), read more and retry. */
1891 if (out_buf.frameCount == 0) {
1892 ALOGW("No frames produced by preproc");
1893 continue;
1894 }
1895
1896 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1897 frames_wr += out_buf.frameCount;
1898 } else {
1899 /* The effect does not comply to the API. In theory, we should never end up here! */
1900 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1901 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1902 frames_wr = frames;
1903 }
1904 }
1905 }
1906 else
1907#endif //PREPROCESSING_ENABLED
1908 {
1909 /* No processing effects attached */
1910 if (has_additional_channels) {
1911 /* With additional channels, we cannot use original buffer */
1912 if (in->proc_buf_size < (size_t)frames) {
1913 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1914 in->proc_buf_size = (size_t)frames;
1915 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1916 ALOG_ASSERT((in->proc_buf_out != NULL),
1917 "process_frames() failed to reallocate proc_buf_out");
1918 proc_buf_out = in->proc_buf_out;
1919 }
1920 }
1921 frames_wr = read_frames(in, proc_buf_out, frames);
1922 }
1923
1924 /* Remove all additional channels that have been added on top of main_channels:
1925 * - aux_channels
1926 * - extra channels from HW due to HW limitations
1927 * Assumption is made that the channels are interleaved and that the main
1928 * channels are first. */
1929
1930 if (has_additional_channels)
1931 {
1932 int16_t* src_buffer = (int16_t *)proc_buf_out;
1933 int16_t* dst_buffer = (int16_t *)buffer;
1934
1935 if (dst_channels == 1) {
1936 for (i = frames_wr; i > 0; i--)
1937 {
1938 *dst_buffer++ = *src_buffer;
1939 src_buffer += src_channels;
1940 }
1941 } else {
1942 for (i = frames_wr; i > 0; i--)
1943 {
1944 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1945 dst_buffer += dst_channels;
1946 src_buffer += src_channels;
1947 }
1948 }
1949 }
1950
1951 return frames_wr;
1952}
1953
1954static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1955 struct resampler_buffer* buffer)
1956{
1957 struct stream_in *in;
1958 struct pcm_device *pcm_device;
1959
1960 if (buffer_provider == NULL || buffer == NULL)
1961 return -EINVAL;
1962
1963 in = (struct stream_in *)((char *)buffer_provider -
1964 offsetof(struct stream_in, buf_provider));
1965
1966 if (list_empty(&in->pcm_dev_list)) {
1967 buffer->raw = NULL;
1968 buffer->frame_count = 0;
1969 in->read_status = -ENODEV;
1970 return -ENODEV;
1971 }
1972
1973 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1974 struct pcm_device, stream_list_node);
1975
1976 if (in->read_buf_frames == 0) {
1977 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1978 if (in->read_buf_size < in->config.period_size) {
1979 in->read_buf_size = in->config.period_size;
1980 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1981 ALOG_ASSERT((in->read_buf != NULL),
1982 "get_next_buffer() failed to reallocate read_buf");
1983 }
1984
1985 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1986
1987 if (in->read_status != 0) {
1988 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1989 buffer->raw = NULL;
1990 buffer->frame_count = 0;
1991 return in->read_status;
1992 }
1993 in->read_buf_frames = in->config.period_size;
1994
1995#ifdef PREPROCESSING_ENABLED
1996#ifdef HW_AEC_LOOPBACK
1997 if (in->hw_echo_reference) {
1998 struct pcm_device *temp_device = NULL;
1999 struct pcm_device *ref_device = NULL;
2000 struct listnode *node = NULL;
2001 struct echo_reference_buffer b;
2002 size_t size_hw_ref_bytes;
2003 size_t size_hw_ref_frames;
2004 int read_status = 0;
2005
2006 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
2007 struct pcm_device, stream_list_node);
2008 list_for_each(node, &in->pcm_dev_list) {
2009 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
2010 if (temp_device->pcm_profile->id == 1) {
2011 ref_device = temp_device;
2012 break;
2013 }
2014 }
2015 if (ref_device) {
2016 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
2017 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
2018 if (in->hw_ref_buf_size < size_hw_ref_frames) {
2019 in->hw_ref_buf_size = size_hw_ref_frames;
2020 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2021 ALOG_ASSERT((in->hw_ref_buf != NULL),
2022 "get_next_buffer() failed to reallocate hw_ref_buf");
2023 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2024 in->hw_ref_buf, size_hw_ref_bytes);
2025 }
2026
2027 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2028 if (read_status != 0) {
2029 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2030 b.raw = NULL;
2031 b.frame_count = 0;
2032 }
2033 else {
2034 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2035 b.raw = (void *)in->hw_ref_buf;
2036 b.frame_count = size_hw_ref_frames;
2037 if (b.delay_ns != 0)
2038 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2039 in->echo_reference->write(in->echo_reference, &b);
2040 }
2041 }
2042 }
2043#endif // HW_AEC_LOOPBACK
2044#endif // PREPROCESSING_ENABLED
2045 }
2046
2047 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2048 in->read_buf_frames : buffer->frame_count;
2049 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2050 in->config.channels;
2051 return in->read_status;
2052}
2053
2054static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2055 struct resampler_buffer* buffer)
2056{
2057 struct stream_in *in;
2058
2059 if (buffer_provider == NULL || buffer == NULL)
2060 return;
2061
2062 in = (struct stream_in *)((char *)buffer_provider -
2063 offsetof(struct stream_in, buf_provider));
2064
2065 in->read_buf_frames -= buffer->frame_count;
2066}
2067
2068/* read_frames() reads frames from kernel driver, down samples to capture rate
2069 * if necessary and output the number of frames requested to the buffer specified */
2070static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2071{
2072 ssize_t frames_wr = 0;
2073
2074 struct pcm_device *pcm_device;
2075
2076 if (list_empty(&in->pcm_dev_list)) {
2077 ALOGE("%s: pcm device list empty", __func__);
2078 return -EINVAL;
2079 }
2080
2081 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2082 struct pcm_device, stream_list_node);
2083
2084 while (frames_wr < frames) {
2085 size_t frames_rd = frames - frames_wr;
2086 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2087 __func__,frames_rd,frames_wr,in->config.channels);
2088 if (in->resampler != NULL) {
2089 in->resampler->resample_from_provider(in->resampler,
2090 (int16_t *)((char *)buffer +
2091 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2092 &frames_rd);
2093 } else {
2094 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002095 .raw = NULL,
2096 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002097 };
2098 get_next_buffer(&in->buf_provider, &buf);
2099 if (buf.raw != NULL) {
2100 memcpy((char *)buffer +
2101 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2102 buf.raw,
2103 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2104 frames_rd = buf.frame_count;
2105 }
2106 release_buffer(&in->buf_provider, &buf);
2107 }
2108 /* in->read_status is updated by getNextBuffer() also called by
2109 * in->resampler->resample_from_provider() */
2110 if (in->read_status != 0)
2111 return in->read_status;
2112
2113 frames_wr += frames_rd;
2114 }
2115 return frames_wr;
2116}
2117
2118static int in_release_pcm_devices(struct stream_in *in)
2119{
2120 struct pcm_device *pcm_device;
2121 struct listnode *node;
2122 struct listnode *next;
2123
2124 list_for_each_safe(node, next, &in->pcm_dev_list) {
2125 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2126 list_remove(node);
2127 free(pcm_device);
2128 }
2129
2130 return 0;
2131}
2132
2133static int stop_input_stream(struct stream_in *in)
2134{
2135 struct audio_usecase *uc_info;
2136 struct audio_device *adev = in->dev;
2137
2138 adev->active_input = NULL;
2139 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2140 in->usecase, use_case_table[in->usecase]);
2141 uc_info = get_usecase_from_id(adev, in->usecase);
2142 if (uc_info == NULL) {
2143 ALOGE("%s: Could not find the usecase (%d) in the list",
2144 __func__, in->usecase);
2145 return -EINVAL;
2146 }
2147
2148 /* Disable the tx device */
2149 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2150
2151 list_remove(&uc_info->adev_list_node);
2152 free(uc_info);
2153
2154 if (list_empty(&in->pcm_dev_list)) {
2155 ALOGE("%s: pcm device list empty", __func__);
2156 return -EINVAL;
2157 }
2158
2159 in_release_pcm_devices(in);
2160 list_init(&in->pcm_dev_list);
2161
2162#ifdef HW_AEC_LOOPBACK
2163 if (in->hw_echo_reference)
2164 {
2165 in->hw_echo_reference = false;
2166 }
2167#endif
2168
2169 ALOGV("%s: exit", __func__);
2170 return 0;
2171}
2172
2173static int start_input_stream(struct stream_in *in)
2174{
2175 /* Enable output device and stream routing controls */
2176 int ret = 0;
2177 bool recreate_resampler = false;
2178 struct audio_usecase *uc_info;
2179 struct audio_device *adev = in->dev;
2180 struct pcm_device_profile *pcm_profile;
2181 struct pcm_device *pcm_device;
2182
2183 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2184 adev->active_input = in;
2185 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2186 if (pcm_profile == NULL) {
2187 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2188 __func__, in->usecase);
2189 ret = -EINVAL;
2190 goto error_config;
2191 }
2192
2193 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002194 if (uc_info == NULL) {
2195 ret = -ENOMEM;
2196 goto error_config;
2197 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002198 uc_info->id = in->usecase;
2199 uc_info->type = PCM_CAPTURE;
2200 uc_info->stream = (struct audio_stream *)in;
2201 uc_info->devices = in->devices;
2202 uc_info->in_snd_device = SND_DEVICE_NONE;
2203 uc_info->out_snd_device = SND_DEVICE_NONE;
2204
2205 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002206 if (pcm_device == NULL) {
2207 free(uc_info);
2208 ret = -ENOMEM;
2209 goto error_config;
2210 }
2211
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002212 pcm_device->pcm_profile = pcm_profile;
2213 list_init(&in->pcm_dev_list);
2214 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2215
2216 list_init(&uc_info->mixer_list);
2217 list_add_tail(&uc_info->mixer_list,
2218 &adev_get_mixer_for_card(adev,
2219 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2220
2221 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2222
2223 select_devices(adev, in->usecase);
2224
2225 /* Config should be updated as profile can be changed between different calls
2226 * to this function:
2227 * - Trigger resampler creation
2228 * - Config needs to be updated */
2229 if (in->config.rate != pcm_profile->config.rate) {
2230 recreate_resampler = true;
2231 }
2232 in->config = pcm_profile->config;
2233
2234#ifdef PREPROCESSING_ENABLED
2235 if (in->aux_channels_changed) {
2236 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2237 recreate_resampler = true;
2238 }
2239#endif
2240
2241 if (in->requested_rate != in->config.rate) {
2242 recreate_resampler = true;
2243 }
2244
2245 if (recreate_resampler) {
2246 if (in->resampler) {
2247 release_resampler(in->resampler);
2248 in->resampler = NULL;
2249 }
2250 in->buf_provider.get_next_buffer = get_next_buffer;
2251 in->buf_provider.release_buffer = release_buffer;
2252 ret = create_resampler(in->config.rate,
2253 in->requested_rate,
2254 in->config.channels,
2255 RESAMPLER_QUALITY_DEFAULT,
2256 &in->buf_provider,
2257 &in->resampler);
2258 }
2259
2260#ifdef PREPROCESSING_ENABLED
2261 if (in->enable_aec && in->echo_reference == NULL) {
2262 in->echo_reference = get_echo_reference(adev,
2263 AUDIO_FORMAT_PCM_16_BIT,
2264 audio_channel_count_from_in_mask(in->main_channels),
2265 in->requested_rate
2266 );
2267 }
2268
2269#ifdef HW_AEC_LOOPBACK
2270 if (in->enable_aec) {
2271 ret = get_hw_echo_reference(in);
2272 if (ret!=0)
2273 goto error_open;
2274
2275 /* force ref buffer reallocation */
2276 in->hw_ref_buf_size = 0;
2277 }
2278#endif
2279#endif
2280
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002281 if (in->dev->voice.in_call) {
2282 ALOGV("%s: in_call, not handling PCMs", __func__);
2283 goto skip_pcm_handling;
2284 }
2285
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002286 /* Open the PCM device.
2287 * The HW is limited to support only the default pcm_profile settings.
2288 * As such a change in aux_channels will not have an effect.
2289 */
2290 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2291 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2292 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2293 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2294
2295 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2296 if (!adev->sound_trigger_open_for_streaming) {
2297 ALOGE("%s: No handle to sound trigger HAL", __func__);
2298 ret = -EIO;
2299 goto error_open;
2300 }
2301 pcm_device->pcm = NULL;
2302 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2303 if (pcm_device->sound_trigger_handle <= 0) {
2304 ALOGE("%s: Failed to open DSP for streaming", __func__);
2305 ret = -EIO;
2306 goto error_open;
2307 }
2308 ALOGV("Opened DSP successfully");
2309 } else {
2310 pcm_device->sound_trigger_handle = 0;
2311 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2312 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2313
2314 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2315 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2316 pcm_close(pcm_device->pcm);
2317 pcm_device->pcm = NULL;
2318 ret = -EIO;
2319 goto error_open;
2320 }
2321 }
2322
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002323skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002324 /* force read and proc buffer reallocation in case of frame size or
2325 * channel count change */
2326 in->proc_buf_frames = 0;
2327 in->proc_buf_size = 0;
2328 in->read_buf_size = 0;
2329 in->read_buf_frames = 0;
2330
2331 /* if no supported sample rate is available, use the resampler */
2332 if (in->resampler) {
2333 in->resampler->reset(in->resampler);
2334 }
2335
2336 ALOGV("%s: exit", __func__);
2337 return ret;
2338
2339error_open:
2340 if (in->resampler) {
2341 release_resampler(in->resampler);
2342 in->resampler = NULL;
2343 }
2344 stop_input_stream(in);
2345
2346error_config:
2347 ALOGV("%s: exit: status(%d)", __func__, ret);
2348 adev->active_input = NULL;
2349 return ret;
2350}
2351
2352void lock_input_stream(struct stream_in *in)
2353{
2354 pthread_mutex_lock(&in->pre_lock);
2355 pthread_mutex_lock(&in->lock);
2356 pthread_mutex_unlock(&in->pre_lock);
2357}
2358
2359void lock_output_stream(struct stream_out *out)
2360{
2361 pthread_mutex_lock(&out->pre_lock);
2362 pthread_mutex_lock(&out->lock);
2363 pthread_mutex_unlock(&out->pre_lock);
2364}
2365
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002366static int uc_release_pcm_devices(struct audio_usecase *usecase)
2367{
2368 struct stream_out *out = (struct stream_out *)usecase->stream;
2369 struct pcm_device *pcm_device;
2370 struct listnode *node;
2371 struct listnode *next;
2372
2373 list_for_each_safe(node, next, &out->pcm_dev_list) {
2374 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2375 list_remove(node);
2376 free(pcm_device);
2377 }
2378 list_init(&usecase->mixer_list);
2379
2380 return 0;
2381}
2382
2383static int uc_select_pcm_devices(struct audio_usecase *usecase)
2384
2385{
2386 struct stream_out *out = (struct stream_out *)usecase->stream;
2387 struct pcm_device *pcm_device;
2388 struct pcm_device_profile *pcm_profile;
2389 struct mixer_card *mixer_card;
2390 audio_devices_t devices = usecase->devices;
2391
2392 list_init(&usecase->mixer_list);
2393 list_init(&out->pcm_dev_list);
2394
2395 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2396 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002397 if (pcm_device == NULL) {
2398 return -ENOMEM;
2399 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002400 pcm_device->pcm_profile = pcm_profile;
2401 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2402 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2403 if (mixer_card == NULL) {
2404 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2405 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2406 }
2407 devices &= ~pcm_profile->devices;
2408 }
2409
2410 return 0;
2411}
2412
2413static int out_close_pcm_devices(struct stream_out *out)
2414{
2415 struct pcm_device *pcm_device;
2416 struct listnode *node;
2417 struct audio_device *adev = out->dev;
2418
2419 list_for_each(node, &out->pcm_dev_list) {
2420 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2421 if (pcm_device->sound_trigger_handle > 0) {
2422 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2423 pcm_device->sound_trigger_handle = 0;
2424 }
2425 if (pcm_device->pcm) {
2426 pcm_close(pcm_device->pcm);
2427 pcm_device->pcm = NULL;
2428 }
2429 if (pcm_device->resampler) {
2430 release_resampler(pcm_device->resampler);
2431 pcm_device->resampler = NULL;
2432 }
2433 if (pcm_device->res_buffer) {
2434 free(pcm_device->res_buffer);
2435 pcm_device->res_buffer = NULL;
2436 }
2437 }
2438
2439 return 0;
2440}
2441
2442static int out_open_pcm_devices(struct stream_out *out)
2443{
2444 struct pcm_device *pcm_device;
2445 struct listnode *node;
2446 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002447 int pcm_device_card;
2448 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002449
2450 list_for_each(node, &out->pcm_dev_list) {
2451 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002452 pcm_device_card = pcm_device->pcm_profile->card;
2453 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002454
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002455 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2456 pcm_device_id = pcm_device_deep_buffer.id;
2457
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002458 if (out->dev->voice.in_call) {
2459 ALOGV("%s: in_call, not opening PCMs", __func__);
2460 return ret;
2461 }
2462
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002463 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2464 __func__, pcm_device_card, pcm_device_id);
2465
2466 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002467 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2468
2469 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2470 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2471 pcm_device->pcm = NULL;
2472 ret = -EIO;
2473 goto error_open;
2474 }
2475 /*
2476 * If the stream rate differs from the PCM rate, we need to
2477 * create a resampler.
2478 */
2479 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2480 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2481 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002482 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002483 out->sample_rate, pcm_device->pcm_profile->config.rate);
2484 ret = create_resampler(out->sample_rate,
2485 pcm_device->pcm_profile->config.rate,
2486 audio_channel_count_from_out_mask(out->channel_mask),
2487 RESAMPLER_QUALITY_DEFAULT,
2488 NULL,
2489 &pcm_device->resampler);
2490 pcm_device->res_byte_count = 0;
2491 pcm_device->res_buffer = NULL;
2492 }
2493 }
2494 return ret;
2495
2496error_open:
2497 out_close_pcm_devices(out);
2498 return ret;
2499}
2500
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002501int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002502{
2503 struct audio_device *adev = out->dev;
2504 struct audio_usecase *uc_info;
2505
2506 uc_info = get_usecase_from_id(adev, out->usecase);
2507 if (uc_info == NULL) {
2508 ALOGE("%s: Could not find the usecase (%d) in the list",
2509 __func__, out->usecase);
2510 return -EINVAL;
2511 }
2512 disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
2513 uc_release_pcm_devices(uc_info);
2514 list_remove(&uc_info->adev_list_node);
2515 free(uc_info);
2516
2517 return 0;
2518}
2519
Andreas Schneider56204f62017-01-31 08:17:32 +01002520int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002521{
2522 struct audio_device *adev = out->dev;
2523 struct audio_usecase *uc_info;
2524
2525 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002526 if (uc_info == NULL) {
2527 return -ENOMEM;
2528 }
2529
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002530 uc_info->id = out->usecase;
2531 uc_info->type = PCM_PLAYBACK;
2532 uc_info->stream = (struct audio_stream *)out;
2533 uc_info->devices = out->devices;
2534 uc_info->in_snd_device = SND_DEVICE_NONE;
2535 uc_info->out_snd_device = SND_DEVICE_NONE;
2536 uc_select_pcm_devices(uc_info);
2537
2538 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2539 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002540
2541 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002542}
2543
2544static int stop_output_stream(struct stream_out *out)
2545{
2546 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002547 bool do_disable = true;
2548
2549 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2550 out->usecase, use_case_table[out->usecase]);
2551
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002552 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002553
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002554 if (do_disable)
2555 ret = disable_output_path_l(out);
2556
2557 ALOGV("%s: exit: status(%d)", __func__, ret);
2558 return ret;
2559}
2560
2561static int start_output_stream(struct stream_out *out)
2562{
2563 int ret = 0;
2564 struct audio_device *adev = out->dev;
2565
2566 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2567 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2568
Andreas Schneider56204f62017-01-31 08:17:32 +01002569 ret = enable_output_path_l(out);
2570 if (ret != 0) {
2571 goto error_config;
2572 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002573
2574 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2575 out->compr = NULL;
2576 ret = out_open_pcm_devices(out);
2577 if (ret != 0)
2578 goto error_open;
2579#ifdef PREPROCESSING_ENABLED
2580 out->echo_reference = NULL;
2581 out->echo_reference_generation = adev->echo_reference_generation;
2582 if (adev->echo_reference != NULL)
2583 out->echo_reference = adev->echo_reference;
2584#endif
2585 } else {
2586 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2587 COMPRESS_IN, &out->compr_config);
2588 if (out->compr && !is_compress_ready(out->compr)) {
2589 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2590 compress_close(out->compr);
2591 out->compr = NULL;
2592 ret = -EIO;
2593 goto error_open;
2594 }
2595 if (out->offload_callback)
2596 compress_nonblock(out->compr, out->non_blocking);
2597
2598 if (adev->offload_fx_start_output != NULL)
2599 adev->offload_fx_start_output(out->handle);
2600 }
2601 ALOGV("%s: exit", __func__);
2602 return 0;
2603error_open:
2604 stop_output_stream(out);
2605error_config:
2606 return ret;
2607}
2608
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002609int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002610{
2611 struct audio_usecase *uc_info;
2612
2613 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002614 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002615
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002616 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002617
2618 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2619 if (uc_info == NULL) {
2620 ALOGE("%s: Could not find the usecase (%d) in the list",
2621 __func__, USECASE_VOICE_CALL);
2622 return -EINVAL;
2623 }
2624
2625 disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
2626 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2627
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002628 list_remove(&uc_info->adev_list_node);
2629 free(uc_info);
2630
2631 ALOGV("%s: exit", __func__);
2632 return 0;
2633}
2634
2635/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002636int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002637{
2638 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002639 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002640
2641 ALOGV("%s: enter", __func__);
2642
2643 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002644 if (uc_info == NULL) {
2645 ret = -ENOMEM;
2646 goto exit;
2647 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002648 /*
2649 * We set this early so that functions called after this is being set
2650 * can use it. It is e.g. needed in select_devices() to inform the RILD
2651 * which output device we use.
2652 */
2653 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002654
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002655 uc_info->id = USECASE_VOICE_CALL;
2656 uc_info->type = VOICE_CALL;
2657 uc_info->stream = (struct audio_stream *)adev->primary_output;
2658 uc_info->devices = adev->primary_output->devices;
2659 uc_info->in_snd_device = SND_DEVICE_NONE;
2660 uc_info->out_snd_device = SND_DEVICE_NONE;
2661
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002662 list_init(&uc_info->mixer_list);
2663 list_add_tail(&uc_info->mixer_list,
2664 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002665
2666 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2667
2668 select_devices(adev, USECASE_VOICE_CALL);
2669
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002670 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002671
2672 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002673 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002674
Andreas Schneider56204f62017-01-31 08:17:32 +01002675exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002676 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002677 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002678}
2679
2680static int check_input_parameters(uint32_t sample_rate,
2681 audio_format_t format,
2682 int channel_count)
2683{
2684 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2685
2686 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2687
2688 switch (sample_rate) {
2689 case 8000:
2690 case 11025:
2691 case 12000:
2692 case 16000:
2693 case 22050:
2694 case 24000:
2695 case 32000:
2696 case 44100:
2697 case 48000:
2698 break;
2699 default:
2700 return -EINVAL;
2701 }
2702
2703 return 0;
2704}
2705
2706static size_t get_input_buffer_size(uint32_t sample_rate,
2707 audio_format_t format,
2708 int channel_count,
2709 usecase_type_t usecase_type,
2710 audio_devices_t devices)
2711{
2712 size_t size = 0;
2713 struct pcm_device_profile *pcm_profile;
2714
2715 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2716 return 0;
2717
2718 pcm_profile = get_pcm_device(usecase_type, devices);
2719 if (pcm_profile == NULL)
2720 return 0;
2721
2722 /*
2723 * take resampling into account and return the closest majoring
2724 * multiple of 16 frames, as audioflinger expects audio buffers to
2725 * be a multiple of 16 frames
2726 */
2727 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2728 size = ((size + 15) / 16) * 16;
2729
2730 return (size * channel_count * audio_bytes_per_sample(format));
2731
2732}
2733
2734static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2735{
2736 struct stream_out *out = (struct stream_out *)stream;
2737
2738 return out->sample_rate;
2739}
2740
2741static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2742{
2743 (void)stream;
2744 (void)rate;
2745 return -ENOSYS;
2746}
2747
2748static size_t out_get_buffer_size(const struct audio_stream *stream)
2749{
2750 struct stream_out *out = (struct stream_out *)stream;
2751
2752 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2753 return out->compr_config.fragment_size;
2754 }
2755
2756 return out->config.period_size *
2757 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2758}
2759
2760static uint32_t out_get_channels(const struct audio_stream *stream)
2761{
2762 struct stream_out *out = (struct stream_out *)stream;
2763
2764 return out->channel_mask;
2765}
2766
2767static audio_format_t out_get_format(const struct audio_stream *stream)
2768{
2769 struct stream_out *out = (struct stream_out *)stream;
2770
2771 return out->format;
2772}
2773
2774static int out_set_format(struct audio_stream *stream, audio_format_t format)
2775{
2776 (void)stream;
2777 (void)format;
2778 return -ENOSYS;
2779}
2780
2781static int do_out_standby_l(struct stream_out *out)
2782{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002783 int status = 0;
2784
2785 out->standby = true;
2786 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2787 out_close_pcm_devices(out);
2788#ifdef PREPROCESSING_ENABLED
2789 /* stop writing to echo reference */
2790 if (out->echo_reference != NULL) {
2791 out->echo_reference->write(out->echo_reference, NULL);
2792 if (out->echo_reference_generation != adev->echo_reference_generation) {
2793 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2794 release_echo_reference(out->echo_reference);
2795 out->echo_reference_generation = adev->echo_reference_generation;
2796 }
2797 out->echo_reference = NULL;
2798 }
2799#endif
2800 } else {
2801 stop_compressed_output_l(out);
2802 out->gapless_mdata.encoder_delay = 0;
2803 out->gapless_mdata.encoder_padding = 0;
2804 if (out->compr != NULL) {
2805 compress_close(out->compr);
2806 out->compr = NULL;
2807 }
2808 }
2809 status = stop_output_stream(out);
2810
2811 return status;
2812}
2813
2814static int out_standby(struct audio_stream *stream)
2815{
2816 struct stream_out *out = (struct stream_out *)stream;
2817 struct audio_device *adev = out->dev;
2818
2819 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2820 out->usecase, use_case_table[out->usecase]);
2821 lock_output_stream(out);
2822 if (!out->standby) {
2823 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002824 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002825 do_out_standby_l(out);
2826 pthread_mutex_unlock(&adev->lock);
2827 }
2828 pthread_mutex_unlock(&out->lock);
2829 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002830
2831 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2832
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002833 return 0;
2834}
2835
2836static int out_dump(const struct audio_stream *stream, int fd)
2837{
2838 (void)stream;
2839 (void)fd;
2840
2841 return 0;
2842}
2843
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002844static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2845{
2846 struct stream_out *out = (struct stream_out *)stream;
2847 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002848 struct listnode *node;
2849 struct str_parms *parms;
2850 char value[32];
2851 int ret, val = 0;
2852 struct audio_usecase *uc_info;
2853 bool do_standby = false;
2854 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002855#ifdef PREPROCESSING_ENABLED
2856 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2857#endif
2858
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002859 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2860 "adev->mode(%#x)",
2861 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2862 out->devices, adev->mode);
2863
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002864 parms = str_parms_create_str(kvpairs);
2865 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2866 if (ret >= 0) {
2867 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002868
2869 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2870 __func__, out->usecase, use_case_table[out->usecase], val,
2871 adev->mode);
2872
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002873 pthread_mutex_lock(&adev->lock_inputs);
2874 lock_output_stream(out);
2875 pthread_mutex_lock(&adev->lock);
2876#ifdef PREPROCESSING_ENABLED
2877 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2878 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2879 /* reset active input:
2880 * - to attach the echo reference
2881 * - because a change in output device may change mic settings */
2882 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2883 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2884 in = adev->active_input;
2885 }
2886 }
2887#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002888 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002889 bool bt_sco_active = false;
2890
2891 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2892 bt_sco_active = true;
2893 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002894 out->devices = val;
2895
2896 if (!out->standby) {
2897 uc_info = get_usecase_from_id(adev, out->usecase);
2898 if (uc_info == NULL) {
2899 ALOGE("%s: Could not find the usecase (%d) in the list",
2900 __func__, out->usecase);
2901 } else {
2902 list_for_each(node, &out->pcm_dev_list) {
2903 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2904 if ((pcm_device->pcm_profile->devices & val) == 0)
2905 do_standby = true;
2906 val &= ~pcm_device->pcm_profile->devices;
2907 }
2908 if (val != 0)
2909 do_standby = true;
2910 }
2911 if (do_standby)
2912 do_out_standby_l(out);
2913 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002914 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2915 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002916 select_devices(adev, out->usecase);
2917 }
2918 }
2919
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002920 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002921 (out == adev->primary_output)) {
2922 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002923 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2924 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002925 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002926 /* Turn on bluetooth if needed */
2927 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002928 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002929 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002930 } else {
2931 /*
2932 * When we select different devices we need to restart the
2933 * voice call. The modem closes the stream on its end and
2934 * we do not get any output.
2935 */
2936 stop_voice_call(adev);
2937 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002938 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002939 }
2940 }
2941
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002942 if ((adev->mode == AUDIO_MODE_NORMAL) && adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002943 (out == adev->primary_output)) {
2944 stop_voice_call(adev);
2945 }
2946 pthread_mutex_unlock(&adev->lock);
2947 pthread_mutex_unlock(&out->lock);
2948#ifdef PREPROCESSING_ENABLED
2949 if (in) {
2950 /* The lock on adev->lock_inputs prevents input stream from being closed */
2951 lock_input_stream(in);
2952 pthread_mutex_lock(&adev->lock);
2953 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2954 do_in_standby_l(in);
2955 pthread_mutex_unlock(&adev->lock);
2956 pthread_mutex_unlock(&in->lock);
2957 }
2958#endif
2959 pthread_mutex_unlock(&adev->lock_inputs);
2960 }
2961
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002962 amplifier_set_parameters(parms);
2963
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002964 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2965 parse_compress_metadata(out, parms);
2966 }
2967
2968 str_parms_destroy(parms);
2969
2970 if (ret > 0)
2971 ret = 0;
2972 ALOGV("%s: exit: code(%d)", __func__, ret);
2973 return ret;
2974}
2975
2976static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2977{
2978 struct stream_out *out = (struct stream_out *)stream;
2979 struct str_parms *query = str_parms_create_str(keys);
2980 char *str;
2981 char value[256];
2982 struct str_parms *reply = str_parms_create();
2983 size_t i, j;
2984 int ret;
2985 bool first = true;
2986 ALOGV("%s: enter: keys - %s", __func__, keys);
2987 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2988 if (ret >= 0) {
2989 value[0] = '\0';
2990 i = 0;
2991 while (out->supported_channel_masks[i] != 0) {
2992 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2993 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2994 if (!first) {
2995 strcat(value, "|");
2996 }
2997 strcat(value, out_channels_name_to_enum_table[j].name);
2998 first = false;
2999 break;
3000 }
3001 }
3002 i++;
3003 }
3004 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
3005 str = str_parms_to_str(reply);
3006 } else {
3007 str = strdup(keys);
3008 }
3009 str_parms_destroy(query);
3010 str_parms_destroy(reply);
3011 ALOGV("%s: exit: returns - %s", __func__, str);
3012 return str;
3013}
3014
3015static uint32_t out_get_latency(const struct audio_stream_out *stream)
3016{
3017 struct stream_out *out = (struct stream_out *)stream;
3018
3019 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3020 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
3021
3022 return (out->config.period_count * out->config.period_size * 1000) /
3023 (out->config.rate);
3024}
3025
3026static int out_set_volume(struct audio_stream_out *stream, float left,
3027 float right)
3028{
3029 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003030
3031 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
3032 /* only take left channel into account: the API is for stereo anyway */
3033 out->muted = (left == 0.0f);
3034 return 0;
3035 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003036 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003037 }
3038
3039 return -ENOSYS;
3040}
3041
Andreas Schneider3b643832017-01-31 11:48:22 +01003042#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003043static int fast_set_affinity(pid_t tid) {
3044 cpu_set_t cpu_set;
3045 int cpu_num;
3046 const char *irq_procfs = "/proc/asound/irq_affinity";
3047 FILE *fp;
3048
3049 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3050 ALOGW("Procfs node %s not found", irq_procfs);
3051 return -1;
3052 }
3053
3054 if (fscanf(fp, "%d", &cpu_num) != 1) {
3055 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3056 fclose(fp);
3057 return -1;
3058 }
3059 fclose(fp);
3060
3061 CPU_ZERO(&cpu_set);
3062 CPU_SET(cpu_num, &cpu_set);
3063 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3064}
Andreas Schneider3b643832017-01-31 11:48:22 +01003065#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003066
3067static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3068 size_t bytes)
3069{
3070 struct stream_out *out = (struct stream_out *)stream;
3071 struct audio_device *adev = out->dev;
3072 ssize_t ret = 0;
3073 struct pcm_device *pcm_device;
3074 struct listnode *node;
3075 size_t frame_size = audio_stream_out_frame_size(stream);
3076 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003077#ifdef PREPROCESSING_ENABLED
3078 size_t in_frames = bytes / frame_size;
3079 size_t out_frames = in_frames;
3080 struct stream_in *in = NULL;
3081#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003082
3083 lock_output_stream(out);
3084
Andreas Schneider3b643832017-01-31 11:48:22 +01003085#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003086 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003087 pid_t tid = gettid();
3088 int err;
3089
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003090 err = fast_set_affinity(tid);
3091 if (err < 0) {
3092 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3093 }
3094 out->is_fastmixer_affinity_set = true;
3095 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003096#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003097
3098 if (out->standby) {
3099#ifdef PREPROCESSING_ENABLED
3100 pthread_mutex_unlock(&out->lock);
3101 /* Prevent input stream from being closed */
3102 pthread_mutex_lock(&adev->lock_inputs);
3103 lock_output_stream(out);
3104 if (!out->standby) {
3105 pthread_mutex_unlock(&adev->lock_inputs);
3106 goto false_alarm;
3107 }
3108#endif
3109 pthread_mutex_lock(&adev->lock);
3110 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003111 if (ret == 0) {
3112 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3113 }
3114
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003115 /* ToDo: If use case is compress offload should return 0 */
3116 if (ret != 0) {
3117 pthread_mutex_unlock(&adev->lock);
3118#ifdef PREPROCESSING_ENABLED
3119 pthread_mutex_unlock(&adev->lock_inputs);
3120#endif
3121 goto exit;
3122 }
3123 out->standby = false;
3124
3125#ifdef PREPROCESSING_ENABLED
3126 /* A change in output device may change the microphone selection */
3127 if (adev->active_input &&
3128 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3129 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3130 in = adev->active_input;
3131 ALOGV("%s: enter:) force_input_standby true", __func__);
3132 }
3133#endif
3134 pthread_mutex_unlock(&adev->lock);
3135#ifdef PREPROCESSING_ENABLED
3136 if (!in) {
3137 /* Leave mutex locked iff in != NULL */
3138 pthread_mutex_unlock(&adev->lock_inputs);
3139 }
3140#endif
3141 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003142#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003143false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003144#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003145
3146 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003147 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003148 return ret;
3149 } else {
3150#ifdef PREPROCESSING_ENABLED
3151 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3152 != out->echo_reference_generation) {
3153 pthread_mutex_lock(&adev->lock);
3154 if (out->echo_reference != NULL) {
3155 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3156 release_echo_reference(out->echo_reference);
3157 }
3158 // note that adev->echo_reference_generation here can be different from the one
3159 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3160 // with what has been set by get_echo_reference() or put_echo_reference()
3161 out->echo_reference_generation = adev->echo_reference_generation;
3162 out->echo_reference = adev->echo_reference;
3163 ALOGV("%s: update echo reference generation %d", __func__,
3164 out->echo_reference_generation);
3165 pthread_mutex_unlock(&adev->lock);
3166 }
3167#endif
3168
3169 if (out->muted)
3170 memset((void *)buffer, 0, bytes);
3171 list_for_each(node, &out->pcm_dev_list) {
3172 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3173 if (pcm_device->resampler) {
3174 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3175 > pcm_device->res_byte_count) {
3176 pcm_device->res_byte_count =
3177 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3178 pcm_device->res_buffer =
3179 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3180 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3181 pcm_device->res_byte_count);
3182 }
3183 frames_rq = bytes / frame_size;
3184 frames_wr = pcm_device->res_byte_count / frame_size;
3185 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3186 __func__, frames_rq, frame_size);
3187 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3188 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3189 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3190 }
3191 if (pcm_device->pcm) {
3192#ifdef PREPROCESSING_ENABLED
3193 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3194 struct echo_reference_buffer b;
3195 b.raw = (void *)buffer;
3196 b.frame_count = in_frames;
3197
3198 get_playback_delay(out, out_frames, &b);
3199 out->echo_reference->write(out->echo_reference, &b);
3200 }
3201#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003202 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3203 if (pcm_device->resampler && pcm_device->res_buffer)
3204 pcm_device->status =
3205 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3206 frames_wr * frame_size);
3207 else
3208 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3209 if (pcm_device->status != 0)
3210 ret = pcm_device->status;
3211 }
3212 }
3213 if (ret == 0)
3214 out->written += bytes / (out->config.channels * sizeof(short));
3215 }
3216
3217exit:
3218 pthread_mutex_unlock(&out->lock);
3219
3220 if (ret != 0) {
3221 list_for_each(node, &out->pcm_dev_list) {
3222 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3223 if (pcm_device->pcm && pcm_device->status != 0)
3224 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3225 }
3226 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003227 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3228 clock_gettime(CLOCK_MONOTONIC, &t);
3229 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3230 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3231 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3232 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3233 if (sleep_time > 0) {
3234 usleep(sleep_time);
3235 } else {
3236 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3237 sleep_time = 0;
3238 }
3239 out->last_write_time_us = now + sleep_time;
3240 // last_write_time_us is an approximation of when the (simulated) alsa
3241 // buffer is believed completely full. The usleep above waits for more space
3242 // in the buffer, but by the end of the sleep the buffer is considered
3243 // topped-off.
3244 //
3245 // On the subsequent out_write(), we measure the elapsed time spent in
3246 // the mixer. This is subtracted from the sleep estimate based on frames,
3247 // thereby accounting for drain in the alsa buffer during mixing.
3248 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003249 }
3250
3251#ifdef PREPROCESSING_ENABLED
3252 if (in) {
3253 /* The lock on adev->lock_inputs prevents input stream from being closed */
3254 lock_input_stream(in);
3255 pthread_mutex_lock(&adev->lock);
3256 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3257 do_in_standby_l(in);
3258 pthread_mutex_unlock(&adev->lock);
3259 pthread_mutex_unlock(&in->lock);
3260 /* This mutex was left locked iff in != NULL */
3261 pthread_mutex_unlock(&adev->lock_inputs);
3262 }
3263#endif
3264
3265 return bytes;
3266}
3267
3268static int out_get_render_position(const struct audio_stream_out *stream,
3269 uint32_t *dsp_frames)
3270{
3271 struct stream_out *out = (struct stream_out *)stream;
3272 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003273 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3274 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003275 } else
3276 return -EINVAL;
3277}
3278
3279static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3280{
3281 (void)stream;
3282 (void)effect;
3283 return 0;
3284}
3285
3286static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3287{
3288 (void)stream;
3289 (void)effect;
3290 return 0;
3291}
3292
3293static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3294 int64_t *timestamp)
3295{
3296 (void)stream;
3297 (void)timestamp;
3298 return -EINVAL;
3299}
3300
3301static int out_get_presentation_position(const struct audio_stream_out *stream,
3302 uint64_t *frames, struct timespec *timestamp)
3303{
3304 struct stream_out *out = (struct stream_out *)stream;
3305 int ret = -1;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003306
3307 lock_output_stream(out);
3308
3309 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003310 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003311 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003312 if (out->dev->voice.in_call) {
3313 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3314 ret = 0;
3315 goto done;
3316 }
3317
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003318 /* FIXME: which device to read from? */
3319 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003320 struct pcm_device *pcm_device;
3321 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003322 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003323
Andreas Schneiderd6359182017-02-08 16:58:22 +01003324 list_for_each(node, &out->pcm_dev_list) {
3325 pcm_device = node_to_item(node,
3326 struct pcm_device,
3327 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003328
Andreas Schneiderd6359182017-02-08 16:58:22 +01003329 if (pcm_device->pcm != NULL) {
3330 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3331 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3332 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3333 /* This adjustment accounts for buffering after app processor.
3334 It is based on estimated DSP latency per use case, rather than exact. */
3335 signed_frames -=
3336 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3337
3338 /* It would be unusual for this value to be negative, but check just in case ... */
3339 if (signed_frames >= 0) {
3340 *frames = signed_frames;
3341 ret = 0;
3342 goto done;
3343 }
3344 ret = -1;
3345 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003346 }
3347 }
3348 }
3349 }
3350
Andreas Schneiderd6359182017-02-08 16:58:22 +01003351done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003352 pthread_mutex_unlock(&out->lock);
3353
3354 return ret;
3355}
3356
3357static int out_set_callback(struct audio_stream_out *stream,
3358 stream_callback_t callback, void *cookie)
3359{
3360 struct stream_out *out = (struct stream_out *)stream;
3361
3362 ALOGV("%s", __func__);
3363 lock_output_stream(out);
3364 out->offload_callback = callback;
3365 out->offload_cookie = cookie;
3366 pthread_mutex_unlock(&out->lock);
3367 return 0;
3368}
3369
3370static int out_pause(struct audio_stream_out* stream)
3371{
3372 struct stream_out *out = (struct stream_out *)stream;
3373 int status = -ENOSYS;
3374 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003375 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3376 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003377 return status;
3378}
3379
3380static int out_resume(struct audio_stream_out* stream)
3381{
3382 struct stream_out *out = (struct stream_out *)stream;
3383 int status = -ENOSYS;
3384 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003385 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3386 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003387 return status;
3388}
3389
3390static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3391{
3392 struct stream_out *out = (struct stream_out *)stream;
3393 int status = -ENOSYS;
3394 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003395 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3396 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003397 return status;
3398}
3399
3400static int out_flush(struct audio_stream_out* stream)
3401{
3402 struct stream_out *out = (struct stream_out *)stream;
3403 ALOGV("%s", __func__);
3404 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003405 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003406 }
3407 return -ENOSYS;
3408}
3409
3410/** audio_stream_in implementation **/
3411static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3412{
3413 struct stream_in *in = (struct stream_in *)stream;
3414
3415 return in->requested_rate;
3416}
3417
3418static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3419{
3420 (void)stream;
3421 (void)rate;
3422 return -ENOSYS;
3423}
3424
3425static uint32_t in_get_channels(const struct audio_stream *stream)
3426{
3427 struct stream_in *in = (struct stream_in *)stream;
3428
3429 return in->main_channels;
3430}
3431
3432static audio_format_t in_get_format(const struct audio_stream *stream)
3433{
3434 (void)stream;
3435 return AUDIO_FORMAT_PCM_16_BIT;
3436}
3437
3438static int in_set_format(struct audio_stream *stream, audio_format_t format)
3439{
3440 (void)stream;
3441 (void)format;
3442
3443 return -ENOSYS;
3444}
3445
3446static size_t in_get_buffer_size(const struct audio_stream *stream)
3447{
3448 struct stream_in *in = (struct stream_in *)stream;
3449
3450 return get_input_buffer_size(in->requested_rate,
3451 in_get_format(stream),
3452 audio_channel_count_from_in_mask(in->main_channels),
3453 in->usecase_type,
3454 in->devices);
3455}
3456
3457static int in_close_pcm_devices(struct stream_in *in)
3458{
3459 struct pcm_device *pcm_device;
3460 struct listnode *node;
3461 struct audio_device *adev = in->dev;
3462
3463 list_for_each(node, &in->pcm_dev_list) {
3464 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3465 if (pcm_device) {
3466 if (pcm_device->pcm)
3467 pcm_close(pcm_device->pcm);
3468 pcm_device->pcm = NULL;
3469 if (pcm_device->sound_trigger_handle > 0)
3470 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3471 pcm_device->sound_trigger_handle = 0;
3472 }
3473 }
3474 return 0;
3475}
3476
3477
3478/* must be called with stream and hw device mutex locked */
3479static int do_in_standby_l(struct stream_in *in)
3480{
3481 int status = 0;
3482
3483#ifdef PREPROCESSING_ENABLED
3484 struct audio_device *adev = in->dev;
3485#endif
3486 if (!in->standby) {
3487
3488 in_close_pcm_devices(in);
3489
3490#ifdef PREPROCESSING_ENABLED
3491 if (in->echo_reference != NULL) {
3492 /* stop reading from echo reference */
3493 in->echo_reference->read(in->echo_reference, NULL);
3494 put_echo_reference(adev, in->echo_reference);
3495 in->echo_reference = NULL;
3496 }
3497#ifdef HW_AEC_LOOPBACK
3498 if (in->hw_echo_reference)
3499 {
3500 if (in->hw_ref_buf) {
3501 free(in->hw_ref_buf);
3502 in->hw_ref_buf = NULL;
3503 }
3504 }
3505#endif // HW_AEC_LOOPBACK
3506#endif // PREPROCESSING_ENABLED
3507
3508 status = stop_input_stream(in);
3509
3510 if (in->read_buf) {
3511 free(in->read_buf);
3512 in->read_buf = NULL;
3513 }
3514
3515 in->standby = 1;
3516 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003517
3518 in->last_read_time_us = 0;
3519
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003520 return 0;
3521}
3522
3523// called with adev->lock_inputs locked
3524static int in_standby_l(struct stream_in *in)
3525{
3526 struct audio_device *adev = in->dev;
3527 int status = 0;
3528 lock_input_stream(in);
3529 if (!in->standby) {
3530 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003531 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003532 status = do_in_standby_l(in);
3533 pthread_mutex_unlock(&adev->lock);
3534 }
3535 pthread_mutex_unlock(&in->lock);
3536 return status;
3537}
3538
3539static int in_standby(struct audio_stream *stream)
3540{
3541 struct stream_in *in = (struct stream_in *)stream;
3542 struct audio_device *adev = in->dev;
3543 int status;
3544 ALOGV("%s: enter", __func__);
3545 pthread_mutex_lock(&adev->lock_inputs);
3546 status = in_standby_l(in);
3547 pthread_mutex_unlock(&adev->lock_inputs);
3548 ALOGV("%s: exit: status(%d)", __func__, status);
3549 return status;
3550}
3551
3552static int in_dump(const struct audio_stream *stream, int fd)
3553{
3554 (void)stream;
3555 (void)fd;
3556
3557 return 0;
3558}
3559
3560static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3561{
3562 struct stream_in *in = (struct stream_in *)stream;
3563 struct audio_device *adev = in->dev;
3564 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003565 char value[32];
3566 int ret, val = 0;
3567 struct audio_usecase *uc_info;
3568 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003569 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003570
3571 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3572 parms = str_parms_create_str(kvpairs);
3573
3574 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3575
3576 pthread_mutex_lock(&adev->lock_inputs);
3577 lock_input_stream(in);
3578 pthread_mutex_lock(&adev->lock);
3579 if (ret >= 0) {
3580 val = atoi(value);
3581 /* no audio source uses val == 0 */
3582 if (((int)in->source != val) && (val != 0)) {
3583 in->source = val;
3584 }
3585 }
3586
3587 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3588 if (ret >= 0) {
3589 val = atoi(value);
3590 if (((int)in->devices != val) && (val != 0)) {
3591 in->devices = val;
3592 /* If recording is in progress, change the tx device to new device */
3593 if (!in->standby) {
3594 uc_info = get_usecase_from_id(adev, in->usecase);
3595 if (uc_info == NULL) {
3596 ALOGE("%s: Could not find the usecase (%d) in the list",
3597 __func__, in->usecase);
3598 } else {
3599 if (list_empty(&in->pcm_dev_list))
3600 ALOGE("%s: pcm device list empty", __func__);
3601 else {
3602 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3603 struct pcm_device, stream_list_node);
3604 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3605 do_standby = true;
3606 }
3607 }
3608 }
3609 if (do_standby) {
3610 ret = do_in_standby_l(in);
3611 } else
3612 ret = select_devices(adev, in->usecase);
3613 }
3614 }
3615 }
3616 pthread_mutex_unlock(&adev->lock);
3617 pthread_mutex_unlock(&in->lock);
3618 pthread_mutex_unlock(&adev->lock_inputs);
3619 str_parms_destroy(parms);
3620
3621 if (ret > 0)
3622 ret = 0;
3623
3624 ALOGV("%s: exit: status(%d)", __func__, ret);
3625 return ret;
3626}
3627
3628static char* in_get_parameters(const struct audio_stream *stream,
3629 const char *keys)
3630{
3631 (void)stream;
3632 (void)keys;
3633
3634 return strdup("");
3635}
3636
3637static int in_set_gain(struct audio_stream_in *stream, float gain)
3638{
3639 (void)stream;
3640 (void)gain;
3641
3642 return 0;
3643}
3644
3645static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3646 size_t bytes)
3647{
3648 struct pcm_device *pcm_device;
3649 struct audio_device *adev = in->dev;
3650
3651 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3652 struct pcm_device, stream_list_node);
3653
3654 if (pcm_device->sound_trigger_handle > 0)
3655 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3656 else
3657 return 0;
3658}
3659
3660static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3661 size_t bytes)
3662{
3663 struct stream_in *in = (struct stream_in *)stream;
3664 struct audio_device *adev = in->dev;
3665 ssize_t frames = -1;
3666 int ret = -1;
3667 int read_and_process_successful = false;
3668
3669 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003670
3671 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3672 lock_input_stream(in);
3673
Andreas Schneider3b643832017-01-31 11:48:22 +01003674#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003675 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003676 pid_t tid = gettid();
3677 int err;
3678
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003679 err = fast_set_affinity(tid);
3680 if (err < 0) {
3681 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3682 }
3683 in->is_fastcapture_affinity_set = true;
3684 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003685#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003686
3687 if (in->standby) {
3688 pthread_mutex_unlock(&in->lock);
3689 pthread_mutex_lock(&adev->lock_inputs);
3690 lock_input_stream(in);
3691 if (!in->standby) {
3692 pthread_mutex_unlock(&adev->lock_inputs);
3693 goto false_alarm;
3694 }
3695 pthread_mutex_lock(&adev->lock);
3696 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003697 if (ret == 0) {
3698 amplifier_input_stream_start(stream);
3699 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003700 pthread_mutex_unlock(&adev->lock);
3701 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003702
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003703 if (ret != 0) {
3704 goto exit;
3705 }
3706 in->standby = 0;
3707 }
3708false_alarm:
3709
3710 if (!list_empty(&in->pcm_dev_list)) {
3711 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3712 bytes = read_bytes_from_dsp(in, buffer, bytes);
3713 if (bytes > 0)
3714 read_and_process_successful = true;
3715 } else {
3716 /*
3717 * Read PCM and:
3718 * - resample if needed
3719 * - process if pre-processors are attached
3720 * - discard unwanted channels
3721 */
3722 frames = read_and_process_frames(in, buffer, frames_rq);
3723 if (frames >= 0)
3724 read_and_process_successful = true;
3725 }
3726 }
3727
3728 /*
3729 * Instead of writing zeroes here, we could trust the hardware
3730 * to always provide zeroes when muted.
3731 */
3732 if (read_and_process_successful == true && adev->mic_mute)
3733 memset(buffer, 0, bytes);
3734
3735exit:
3736 pthread_mutex_unlock(&in->lock);
3737
3738 if (read_and_process_successful == false) {
3739 in_standby(&in->stream.common);
3740 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003741 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3742 clock_gettime(CLOCK_MONOTONIC, &t);
3743 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3744
3745 // we do a full sleep when exiting standby.
3746 const bool standby = in->last_read_time_us == 0;
3747 const int64_t elapsed_time_since_last_read = standby ?
3748 0 : now - in->last_read_time_us;
3749 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3750 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3751 if (sleep_time > 0) {
3752 usleep(sleep_time);
3753 } else {
3754 sleep_time = 0;
3755 }
3756 in->last_read_time_us = now + sleep_time;
3757 // last_read_time_us is an approximation of when the (simulated) alsa
3758 // buffer is drained by the read, and is empty.
3759 //
3760 // On the subsequent in_read(), we measure the elapsed time spent in
3761 // the recording thread. This is subtracted from the sleep estimate based on frames,
3762 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003763 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003764 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003765
3766 if (bytes > 0) {
3767 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3768 }
3769
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003770 return bytes;
3771}
3772
3773static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3774{
3775 (void)stream;
3776
3777 return 0;
3778}
3779
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003780static int in_get_capture_position(const struct audio_stream_in *stream,
3781 int64_t *frames, int64_t *time)
3782{
3783 if (stream == NULL || frames == NULL || time == NULL) {
3784 return -EINVAL;
3785 }
3786
3787 struct stream_in *in = (struct stream_in *)stream;
3788 struct pcm_device *pcm_device;
3789 int ret = -ENOSYS;
3790
3791 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3792 struct pcm_device, stream_list_node);
3793
3794 pthread_mutex_lock(&in->lock);
3795 if (pcm_device->pcm) {
3796 struct timespec timestamp;
3797 unsigned int avail;
3798 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3799 *frames = in->frames_read + avail;
3800 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3801 ret = 0;
3802 }
3803 }
3804
3805 pthread_mutex_unlock(&in->lock);
3806 return ret;
3807}
3808
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003809static int add_remove_audio_effect(const struct audio_stream *stream,
3810 effect_handle_t effect,
3811 bool enable)
3812{
3813 struct stream_in *in = (struct stream_in *)stream;
3814 struct audio_device *adev = in->dev;
3815 int status = 0;
3816 effect_descriptor_t desc;
3817#ifdef PREPROCESSING_ENABLED
3818 int i;
3819#endif
3820 status = (*effect)->get_descriptor(effect, &desc);
3821 if (status != 0)
3822 return status;
3823
3824 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3825
3826 pthread_mutex_lock(&adev->lock_inputs);
3827 lock_input_stream(in);
3828 pthread_mutex_lock(&in->dev->lock);
3829#ifndef PREPROCESSING_ENABLED
3830 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3831 in->enable_aec != enable &&
3832 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3833 in->enable_aec = enable;
3834 if (!in->standby)
3835 select_devices(in->dev, in->usecase);
3836 }
3837#else
3838 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3839 status = -ENOSYS;
3840 goto exit;
3841 }
3842 if ( enable == true ) {
3843 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3844 /* add the supported channel of the effect in the channel_configs */
3845 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3846 in->num_preprocessors ++;
3847 /* check compatibility between main channel supported and possible auxiliary channels */
3848 in_update_aux_channels(in, effect);//wesley crash
3849 in->aux_channels_changed = true;
3850 } else {
3851 /* if ( enable == false ) */
3852 if (in->num_preprocessors <= 0) {
3853 status = -ENOSYS;
3854 goto exit;
3855 }
3856 status = -EINVAL;
3857 for (i=0; i < in->num_preprocessors; i++) {
3858 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3859 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3860 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3861 in->preprocessors[i - 1].num_channel_configs =
3862 in->preprocessors[i].num_channel_configs;
3863 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3864 continue;
3865 }
3866 if ( in->preprocessors[i].effect_itfe == effect ) {
3867 ALOGV("add_remove_audio_effect found fx at index %d", i);
3868 free(in->preprocessors[i].channel_configs);
3869 status = 0;
3870 }
3871 }
3872 if (status != 0)
3873 goto exit;
3874 in->num_preprocessors--;
3875 /* if we remove one effect, at least the last proproc should be reset */
3876 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3877 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3878 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3879 in->aux_channels_changed = false;
3880 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3881 }
3882 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3883
3884 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3885 in->enable_aec = enable;
3886 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3887 if (!in->standby) {
3888 select_devices(in->dev, in->usecase);
3889 do_in_standby_l(in);
3890 }
3891 if (in->enable_aec == true) {
3892 in_configure_reverse(in);
3893 }
3894 }
3895exit:
3896#endif
3897 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3898 pthread_mutex_unlock(&in->dev->lock);
3899 pthread_mutex_unlock(&in->lock);
3900 pthread_mutex_unlock(&adev->lock_inputs);
3901 return status;
3902}
3903
3904static int in_add_audio_effect(const struct audio_stream *stream,
3905 effect_handle_t effect)
3906{
3907 ALOGV("%s: effect %p", __func__, effect);
3908 return add_remove_audio_effect(stream, effect, true);
3909}
3910
3911static int in_remove_audio_effect(const struct audio_stream *stream,
3912 effect_handle_t effect)
3913{
3914 ALOGV("%s: effect %p", __func__, effect);
3915 return add_remove_audio_effect(stream, effect, false);
3916}
3917
3918static int adev_open_output_stream(struct audio_hw_device *dev,
3919 audio_io_handle_t handle,
3920 audio_devices_t devices,
3921 audio_output_flags_t flags,
3922 struct audio_config *config,
3923 struct audio_stream_out **stream_out,
3924 const char *address __unused)
3925{
3926 struct audio_device *adev = (struct audio_device *)dev;
3927 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003928 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003929 struct pcm_device_profile *pcm_profile;
3930
3931 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3932 __func__, config->sample_rate, config->channel_mask, devices, flags);
3933 *stream_out = NULL;
3934 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003935 if (out == NULL) {
3936 ret = -ENOMEM;
3937 goto error_config;
3938 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003939
3940 if (devices == AUDIO_DEVICE_NONE)
3941 devices = AUDIO_DEVICE_OUT_SPEAKER;
3942
3943 out->flags = flags;
3944 out->devices = devices;
3945 out->dev = adev;
3946 out->format = config->format;
3947 out->sample_rate = config->sample_rate;
3948 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3949 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3950 out->handle = handle;
3951
3952 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3953 if (pcm_profile == NULL) {
3954 ret = -EINVAL;
3955 goto error_open;
3956 }
3957 out->config = pcm_profile->config;
3958
3959 /* Init use case and pcm_config */
3960 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3961 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3962 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3963 ALOGE("%s: Unsupported Offload information", __func__);
3964 ret = -EINVAL;
3965 goto error_open;
3966 }
3967 if (!is_supported_format(config->offload_info.format)) {
3968 ALOGE("%s: Unsupported audio format", __func__);
3969 ret = -EINVAL;
3970 goto error_open;
3971 }
3972
3973 out->compr_config.codec = (struct snd_codec *)
3974 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003975 if (out->compr_config.codec == NULL) {
3976 ret = -ENOMEM;
3977 goto error_open;
3978 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003979
3980 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3981 if (config->offload_info.channel_mask)
3982 out->channel_mask = config->offload_info.channel_mask;
3983 else if (config->channel_mask)
3984 out->channel_mask = config->channel_mask;
3985 out->format = config->offload_info.format;
3986 out->sample_rate = config->offload_info.sample_rate;
3987
3988 out->stream.set_callback = out_set_callback;
3989 out->stream.pause = out_pause;
3990 out->stream.resume = out_resume;
3991 out->stream.drain = out_drain;
3992 out->stream.flush = out_flush;
3993
3994 out->compr_config.codec->id =
3995 get_snd_codec_id(config->offload_info.format);
3996 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3997 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3998 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3999 out->compr_config.codec->bit_rate =
4000 config->offload_info.bit_rate;
4001 out->compr_config.codec->ch_in =
4002 audio_channel_count_from_out_mask(config->channel_mask);
4003 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4004
4005 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4006 out->non_blocking = 1;
4007
4008 out->send_new_metadata = 1;
4009 create_offload_callback_thread(out);
4010 out->offload_state = OFFLOAD_STATE_IDLE;
4011
4012 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4013 __func__, config->offload_info.version,
4014 config->offload_info.bit_rate);
4015 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4016 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004017 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004018 out->sample_rate = out->config.rate;
4019 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4020 } else {
4021 out->usecase = USECASE_AUDIO_PLAYBACK;
4022 out->sample_rate = out->config.rate;
4023 }
4024
4025 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4026 if (adev->primary_output == NULL)
4027 adev->primary_output = out;
4028 else {
4029 ALOGE("%s: Primary output is already opened", __func__);
4030 ret = -EEXIST;
4031 goto error_open;
4032 }
4033 }
4034
4035 /* Check if this usecase is already existing */
4036 pthread_mutex_lock(&adev->lock);
4037 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4038 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4039 pthread_mutex_unlock(&adev->lock);
4040 ret = -EEXIST;
4041 goto error_open;
4042 }
4043 pthread_mutex_unlock(&adev->lock);
4044
4045 out->stream.common.get_sample_rate = out_get_sample_rate;
4046 out->stream.common.set_sample_rate = out_set_sample_rate;
4047 out->stream.common.get_buffer_size = out_get_buffer_size;
4048 out->stream.common.get_channels = out_get_channels;
4049 out->stream.common.get_format = out_get_format;
4050 out->stream.common.set_format = out_set_format;
4051 out->stream.common.standby = out_standby;
4052 out->stream.common.dump = out_dump;
4053 out->stream.common.set_parameters = out_set_parameters;
4054 out->stream.common.get_parameters = out_get_parameters;
4055 out->stream.common.add_audio_effect = out_add_audio_effect;
4056 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4057 out->stream.get_latency = out_get_latency;
4058 out->stream.set_volume = out_set_volume;
4059 out->stream.write = out_write;
4060 out->stream.get_render_position = out_get_render_position;
4061 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4062 out->stream.get_presentation_position = out_get_presentation_position;
4063
4064 out->standby = 1;
4065 /* out->muted = false; by calloc() */
4066 /* out->written = 0; by calloc() */
4067
4068 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4069 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4070 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4071
4072 config->format = out->stream.common.get_format(&out->stream.common);
4073 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4074 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4075
4076 out->is_fastmixer_affinity_set = false;
4077
4078 *stream_out = &out->stream;
4079 ALOGV("%s: exit", __func__);
4080 return 0;
4081
4082error_open:
4083 free(out);
4084 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004085error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004086 ALOGV("%s: exit: ret %d", __func__, ret);
4087 return ret;
4088}
4089
4090static void adev_close_output_stream(struct audio_hw_device *dev,
4091 struct audio_stream_out *stream)
4092{
4093 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004094 (void)dev;
4095
4096 ALOGV("%s: enter", __func__);
4097 out_standby(&stream->common);
4098 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4099 destroy_offload_callback_thread(out);
4100
4101 if (out->compr_config.codec != NULL)
4102 free(out->compr_config.codec);
4103 }
4104 pthread_cond_destroy(&out->cond);
4105 pthread_mutex_destroy(&out->lock);
4106 free(stream);
4107 ALOGV("%s: exit", __func__);
4108}
4109
4110static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4111{
4112 struct audio_device *adev = (struct audio_device *)dev;
4113 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004114 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004115#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004116 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004117#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004118 int ret;
4119
4120 ALOGV("%s: enter: %s", __func__, kvpairs);
4121
4122 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004123
Andreas Schneider05bc1882017-02-09 14:03:11 +01004124 /******************************************************
4125 *** BT SCO
4126 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004127 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4128 if (ret >= 0) {
4129 /* When set to false, HAL should disable EC and NS
4130 * But it is currently not supported.
4131 */
4132 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004133 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004134 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004135 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004136 }
4137
Andreas Schneider05bc1882017-02-09 14:03:11 +01004138 ret = str_parms_get_str(parms,
4139 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4140 value,
4141 sizeof(value));
4142 if (ret >= 0) {
4143 /* TODO: Add support in voice calls */
4144 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4145 adev->voice.bluetooth_wb = true;
4146 ALOGI("%s: Implement support for BT SCO wideband calls!!!",
4147 __func__);
4148 } else {
4149 adev->voice.bluetooth_wb = false;
4150 }
4151 }
4152
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004153 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4154 if (ret >= 0) {
4155 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4156 adev->screen_off = false;
4157 else
4158 adev->screen_off = true;
4159 }
4160
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004161#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004162 ret = str_parms_get_int(parms, "rotation", &val);
4163 if (ret >= 0) {
4164 bool reverse_speakers = false;
4165 switch(val) {
4166 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4167 relative to the user when the device is rotated 90deg from its default rotation. This
4168 assumption is device-specific, not platform-specific like this code. */
4169 case 270:
4170 reverse_speakers = true;
4171 break;
4172 case 0:
4173 case 90:
4174 case 180:
4175 break;
4176 default:
4177 ALOGE("%s: unexpected rotation of %d", __func__, val);
4178 }
4179 pthread_mutex_lock(&adev->lock);
4180 if (adev->speaker_lr_swap != reverse_speakers) {
4181 adev->speaker_lr_swap = reverse_speakers;
4182 /* only update the selected device if there is active pcm playback */
4183 struct audio_usecase *usecase;
4184 struct listnode *node;
4185 list_for_each(node, &adev->usecase_list) {
4186 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4187 if (usecase->type == PCM_PLAYBACK) {
4188 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004189 break;
4190 }
4191 }
4192 }
4193 pthread_mutex_unlock(&adev->lock);
4194 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004195#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004196
4197 str_parms_destroy(parms);
4198
4199 if (ret > 0)
4200 ret = 0;
4201
4202 ALOGV("%s: exit with code(%d)", __func__, ret);
4203 return ret;
4204}
4205
4206static char* adev_get_parameters(const struct audio_hw_device *dev,
4207 const char *keys)
4208{
4209 (void)dev;
4210 (void)keys;
4211
4212 return strdup("");
4213}
4214
4215static int adev_init_check(const struct audio_hw_device *dev)
4216{
4217 (void)dev;
4218
4219 return 0;
4220}
4221
4222static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4223{
4224 int ret = 0;
4225 struct audio_device *adev = (struct audio_device *)dev;
4226 pthread_mutex_lock(&adev->lock);
4227 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004228 adev->voice.volume = volume;
4229 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004230 pthread_mutex_unlock(&adev->lock);
4231 return ret;
4232}
4233
4234static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4235{
4236 (void)dev;
4237 (void)volume;
4238
4239 return -ENOSYS;
4240}
4241
4242static int adev_get_master_volume(struct audio_hw_device *dev,
4243 float *volume)
4244{
4245 (void)dev;
4246 (void)volume;
4247
4248 return -ENOSYS;
4249}
4250
4251static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4252{
4253 (void)dev;
4254 (void)muted;
4255
4256 return -ENOSYS;
4257}
4258
4259static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4260{
4261 (void)dev;
4262 (void)muted;
4263
4264 return -ENOSYS;
4265}
4266
4267static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4268{
4269 struct audio_device *adev = (struct audio_device *)dev;
4270
4271 pthread_mutex_lock(&adev->lock);
4272 if (adev->mode != mode) {
4273 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004274 if (amplifier_set_mode(mode) != 0) {
4275 ALOGE("Failed setting amplifier mode");
4276 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004277 adev->mode = mode;
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;
4553
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004554 /* adev->cur_hdmi_channels = 0; by calloc() */
4555 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004556 if (adev->snd_dev_ref_cnt == NULL) {
4557 free(adev);
4558 return -ENOMEM;
4559 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004560
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004561 adev->ns_in_voice_rec = false;
4562
4563 list_init(&adev->usecase_list);
4564
4565 if (mixer_init(adev) != 0) {
4566 free(adev->snd_dev_ref_cnt);
4567 free(adev);
4568 ALOGE("%s: Failed to init, aborting.", __func__);
4569 *device = NULL;
4570 return -EINVAL;
4571 }
4572
4573 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4574 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4575 if (adev->offload_fx_lib == NULL) {
4576 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4577 } else {
4578 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4579 adev->offload_fx_start_output =
4580 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4581 "visualizer_hal_start_output");
4582 adev->offload_fx_stop_output =
4583 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4584 "visualizer_hal_stop_output");
4585 }
4586 }
4587
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004588 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4589 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4590 if (adev->sound_trigger_lib == NULL) {
4591 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4592 } else {
4593 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4594 adev->sound_trigger_open_for_streaming =
4595 (int (*)(void))dlsym(adev->sound_trigger_lib,
4596 "sound_trigger_open_for_streaming");
4597 adev->sound_trigger_read_samples =
4598 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4599 "sound_trigger_read_samples");
4600 adev->sound_trigger_close_for_streaming =
4601 (int (*)(int))dlsym(adev->sound_trigger_lib,
4602 "sound_trigger_close_for_streaming");
4603 if (!adev->sound_trigger_open_for_streaming ||
4604 !adev->sound_trigger_read_samples ||
4605 !adev->sound_trigger_close_for_streaming) {
4606
4607 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4608 adev->sound_trigger_open_for_streaming = 0;
4609 adev->sound_trigger_read_samples = 0;
4610 adev->sound_trigger_close_for_streaming = 0;
4611 }
4612 }
4613 }
4614
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004615 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004616 if (adev->voice.session == NULL) {
4617 ALOGE("%s: Failed to initialize voice session data", __func__);
4618
4619 free(adev->snd_dev_ref_cnt);
4620 free(adev);
4621
4622 *device = NULL;
4623 return -EINVAL;
4624 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004625
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004626 if (amplifier_open() != 0) {
4627 ALOGE("Amplifier initialization failed");
4628 }
4629
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004630 *device = &adev->device.common;
4631
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004632 audio_device_ref_count++;
4633
4634 char value[PROPERTY_VALUE_MAX];
4635 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4636 int trial = atoi(value);
4637 if (period_size_is_plausible_for_low_latency(trial)) {
4638
4639 pcm_device_playback.config.period_size = trial;
4640 pcm_device_playback.config.start_threshold =
4641 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4642 pcm_device_playback.config.stop_threshold =
4643 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4644
4645 pcm_device_capture_low_latency.config.period_size = trial;
4646 }
4647 }
4648
4649 ALOGV("%s: exit", __func__);
4650 return 0;
4651}
4652
4653static struct hw_module_methods_t hal_module_methods = {
4654 .open = adev_open,
4655};
4656
4657struct audio_module HAL_MODULE_INFO_SYM = {
4658 .common = {
4659 .tag = HARDWARE_MODULE_TAG,
4660 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4661 .hal_api_version = HARDWARE_HAL_API_VERSION,
4662 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004663 .name = "Samsung Audio HAL",
4664 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004665 .methods = &hal_module_methods,
4666 },
4667};