blob: 0f8a2a6fd556375b2cb4d77b593a1dd97698d450 [file] [log] [blame]
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001/*
2 * Copyright (C) 2013 The Android Open Source Project
Christopher N. Hesse2f6f8582017-01-28 12:46:15 +01003 * Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
Andreas Schneider759368f2017-02-02 16:11:14 +01004 * Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org>
Christopher N. Hesse297a6362017-01-28 12:40:45 +01005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#define LOG_TAG "audio_hw_primary"
20/*#define LOG_NDEBUG 0*/
21/*#define VERY_VERY_VERBOSE_LOGGING*/
22#ifdef VERY_VERY_VERBOSE_LOGGING
23#define ALOGVV ALOGV
24#else
25#define ALOGVV(a...) do { } while(0)
26#endif
27
28#define _GNU_SOURCE
29#include <errno.h>
30#include <pthread.h>
31#include <stdint.h>
32#include <sys/time.h>
33#include <stdlib.h>
34#include <math.h>
35#include <dlfcn.h>
Christopher N. Hesse297a6362017-01-28 12:40:45 +010036
37#include <cutils/log.h>
38#include <cutils/str_parms.h>
39#include <cutils/atomic.h>
40#include <cutils/sched_policy.h>
41#include <cutils/properties.h>
42
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010043#include <samsung_audio.h>
44
Christopher N. Hesse297a6362017-01-28 12:40:45 +010045#include <hardware/audio_effect.h>
46#include <system/thread_defs.h>
47#include <audio_effects/effect_aec.h>
48#include <audio_effects/effect_ns.h>
49#include "audio_hw.h"
Christopher N. Hesse757ac412017-01-28 14:42:48 +010050#include "compress_offload.h"
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +010051#include "voice.h"
Christopher N. Hesse297a6362017-01-28 12:40:45 +010052
53#include "sound/compress_params.h"
54
Christopher N. Hesse297a6362017-01-28 12:40:45 +010055
56/* TODO: the following PCM device profiles could be read from a config file */
57static struct pcm_device_profile pcm_device_playback = {
58 .config = {
59 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
60 .rate = PLAYBACK_DEFAULT_SAMPLING_RATE,
61 .period_size = PLAYBACK_PERIOD_SIZE,
62 .period_count = PLAYBACK_PERIOD_COUNT,
63 .format = PCM_FORMAT_S16_LE,
64 .start_threshold = PLAYBACK_START_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
65 .stop_threshold = PLAYBACK_STOP_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
66 .silence_threshold = 0,
67 .silence_size = UINT_MAX,
68 .avail_min = PLAYBACK_AVAILABLE_MIN,
69 },
70 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010071 .id = SOUND_PLAYBACK_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010072 .type = PCM_PLAYBACK,
73 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010074 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010075};
76
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010077static struct pcm_device_profile pcm_device_deep_buffer = {
78 .config = {
79 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
80 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
81 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
82 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
83 .format = PCM_FORMAT_S16_LE,
84 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
85 .stop_threshold = INT_MAX,
86 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
87 },
88 .card = SOUND_CARD,
89 .id = SOUND_DEEP_BUFFER_DEVICE,
90 .type = PCM_PLAYBACK,
91 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010092 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010093};
94
Christopher N. Hesse297a6362017-01-28 12:40:45 +010095static struct pcm_device_profile pcm_device_capture = {
96 .config = {
97 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
98 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
99 .period_size = CAPTURE_PERIOD_SIZE,
100 .period_count = CAPTURE_PERIOD_COUNT,
101 .format = PCM_FORMAT_S16_LE,
102 .start_threshold = CAPTURE_START_THRESHOLD,
103 .stop_threshold = 0,
104 .silence_threshold = 0,
105 .avail_min = 0,
106 },
107 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100108 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100109 .type = PCM_CAPTURE,
110 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
111};
112
113static struct pcm_device_profile pcm_device_capture_low_latency = {
114 .config = {
115 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
116 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
117 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
118 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
119 .format = PCM_FORMAT_S16_LE,
120 .start_threshold = CAPTURE_START_THRESHOLD,
121 .stop_threshold = 0,
122 .silence_threshold = 0,
123 .avail_min = 0,
124 },
125 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100126 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100127 .type = PCM_CAPTURE_LOW_LATENCY,
128 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
129};
130
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100131#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100132static struct pcm_device_profile pcm_device_capture_loopback_aec = {
133 .config = {
134 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
135 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
136 .period_size = CAPTURE_PERIOD_SIZE,
137 .period_count = CAPTURE_PERIOD_COUNT,
138 .format = PCM_FORMAT_S16_LE,
139 .start_threshold = CAPTURE_START_THRESHOLD,
140 .stop_threshold = 0,
141 .silence_threshold = 0,
142 .avail_min = 0,
143 },
144 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100145 .id = SOUND_CAPTURE_LOOPBACK_AEC_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100146 .type = PCM_CAPTURE,
147 .devices = SND_DEVICE_IN_LOOPBACK_AEC,
148};
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100149#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100150
151static struct pcm_device_profile pcm_device_playback_sco = {
152 .config = {
153 .channels = SCO_DEFAULT_CHANNEL_COUNT,
154 .rate = SCO_DEFAULT_SAMPLING_RATE,
155 .period_size = SCO_PERIOD_SIZE,
156 .period_count = SCO_PERIOD_COUNT,
157 .format = PCM_FORMAT_S16_LE,
158 .start_threshold = SCO_START_THRESHOLD,
159 .stop_threshold = SCO_STOP_THRESHOLD,
160 .silence_threshold = 0,
161 .avail_min = SCO_AVAILABLE_MIN,
162 },
163 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100164 .id = SOUND_PLAYBACK_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100165 .type = PCM_PLAYBACK,
166 .devices =
167 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
168 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
169};
170
171static struct pcm_device_profile pcm_device_capture_sco = {
172 .config = {
173 .channels = SCO_DEFAULT_CHANNEL_COUNT,
174 .rate = SCO_DEFAULT_SAMPLING_RATE,
175 .period_size = SCO_PERIOD_SIZE,
176 .period_count = SCO_PERIOD_COUNT,
177 .format = PCM_FORMAT_S16_LE,
178 .start_threshold = CAPTURE_START_THRESHOLD,
179 .stop_threshold = 0,
180 .silence_threshold = 0,
181 .avail_min = 0,
182 },
183 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100184 .id = SOUND_CAPTURE_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100185 .type = PCM_CAPTURE,
186 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
187};
188
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100189#ifdef SOUND_CAPTURE_HOTWORD_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100190static struct pcm_device_profile pcm_device_hotword_streaming = {
191 .config = {
192 .channels = 1,
193 .rate = 16000,
194 .period_size = CAPTURE_PERIOD_SIZE,
195 .period_count = CAPTURE_PERIOD_COUNT,
196 .format = PCM_FORMAT_S16_LE,
197 .start_threshold = CAPTURE_START_THRESHOLD,
198 .stop_threshold = 0,
199 .silence_threshold = 0,
200 .avail_min = 0,
201 },
202 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100203 .id = SOUND_CAPTURE_HOTWORD_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100204 .type = PCM_HOTWORD_STREAMING,
205 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC
206};
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100207#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100208
209static struct pcm_device_profile * const pcm_devices[] = {
210 &pcm_device_playback,
211 &pcm_device_capture,
212 &pcm_device_capture_low_latency,
213 &pcm_device_playback_sco,
214 &pcm_device_capture_sco,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100215#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100216 &pcm_device_capture_loopback_aec,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100217#endif
218#ifdef SOUND_CAPTURE_HOTWORD_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100219 &pcm_device_hotword_streaming,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100220#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100221 NULL,
222};
223
224static const char * const use_case_table[AUDIO_USECASE_MAX] = {
225 [USECASE_AUDIO_PLAYBACK] = "playback",
226 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
227 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
Andreas Schneiderdf6fc8a2017-02-14 11:38:41 +0100228 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback deep-buffer",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100229 [USECASE_AUDIO_CAPTURE] = "capture",
230 [USECASE_AUDIO_CAPTURE_HOTWORD] = "capture-hotword",
231 [USECASE_VOICE_CALL] = "voice-call",
232};
233
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100234#define STRING_TO_ENUM(string) { #string, string }
235
236static unsigned int audio_device_ref_count;
237
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100238struct string_to_enum {
239 const char *name;
240 uint32_t value;
241};
242
243static const struct string_to_enum out_channels_name_to_enum_table[] = {
244 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
245 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
246 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
247};
248
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200249static struct audio_device *adev = NULL;
250
251static amplifier_device_t * get_amplifier_device(void)
252{
253 if (adev)
254 return adev->amp;
255
256 return NULL;
257}
258
259static int amplifier_open(void)
260{
261 int rc;
262 amplifier_module_t *module;
263
264 rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
265 (const hw_module_t **) &module);
266 if (rc) {
267 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
268 __func__, strerror(-rc));
269 return -ENODEV;
270 }
271
272 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
273 if (rc) {
274 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
275 __func__, strerror(-rc));
276 return -ENODEV;
277 }
278
279 return 0;
280}
281
282static int amplifier_set_input_devices(uint32_t devices)
283{
284 amplifier_device_t *amp = get_amplifier_device();
285 if (amp && amp->set_input_devices)
286 return amp->set_input_devices(amp, devices);
287
288 return 0;
289}
290
291static int amplifier_set_output_devices(uint32_t devices)
292{
293 amplifier_device_t *amp = get_amplifier_device();
294 if (amp && amp->set_output_devices)
295 return amp->set_output_devices(amp, devices);
296
297 return 0;
298}
299
300static int amplifier_enable_devices(uint32_t devices, bool enable)
301{
302 amplifier_device_t *amp = get_amplifier_device();
303 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
304 devices < SND_DEVICE_OUT_END;
305
306 if (amp && amp->enable_output_devices && is_output)
307 return amp->enable_output_devices(amp, devices, enable);
308
309 if (amp && amp->enable_input_devices && !is_output)
310 return amp->enable_input_devices(amp, devices, enable);
311
312 return 0;
313}
314
315static int amplifier_set_mode(audio_mode_t mode)
316{
317 amplifier_device_t *amp = get_amplifier_device();
318 if (amp && amp->set_mode)
319 return amp->set_mode(amp, mode);
320
321 return 0;
322}
323
324static int amplifier_output_stream_start(struct audio_stream_out *stream,
325 bool offload)
326{
327 amplifier_device_t *amp = get_amplifier_device();
328 if (amp && amp->output_stream_start)
329 return amp->output_stream_start(amp, stream, offload);
330
331 return 0;
332}
333
334static int amplifier_input_stream_start(struct audio_stream_in *stream)
335{
336 amplifier_device_t *amp = get_amplifier_device();
337 if (amp && amp->input_stream_start)
338 return amp->input_stream_start(amp, stream);
339
340 return 0;
341}
342
343static int amplifier_output_stream_standby(struct audio_stream_out *stream)
344{
345 amplifier_device_t *amp = get_amplifier_device();
346 if (amp && amp->output_stream_standby)
347 return amp->output_stream_standby(amp, stream);
348
349 return 0;
350}
351
352static int amplifier_input_stream_standby(struct audio_stream_in *stream)
353{
354 amplifier_device_t *amp = get_amplifier_device();
355 if (amp && amp->input_stream_standby)
356 return amp->input_stream_standby(amp, stream);
357
358 return 0;
359}
360
361static int amplifier_set_parameters(struct str_parms *parms)
362{
363 amplifier_device_t *amp = get_amplifier_device();
364 if (amp && amp->set_parameters)
365 return amp->set_parameters(amp, parms);
366
367 return 0;
368}
369
370static int amplifier_close(void)
371{
372 amplifier_device_t *amp = get_amplifier_device();
373 if (amp)
374 amplifier_device_close(amp);
375
376 return 0;
377}
378
Andreas Schneider759368f2017-02-02 16:11:14 +0100379struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
380 struct timespec ret;
381 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100382
383 if (time0.tv_nsec > time1.tv_nsec) {
384 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
385 time0.tv_nsec -= (long int) (1E9 * xsec);
386 time0.tv_sec += xsec;
387 }
388
389 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
390 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
391 time0.tv_nsec += (long int) (1E9 * xsec);
392 time0.tv_sec -= xsec;
393 }
394
Paul Keithf114e2e2017-02-14 20:41:33 -0600395 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
396 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100397
398 return ret;
399}
400
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100401static bool is_supported_format(audio_format_t format)
402{
403 if (format == AUDIO_FORMAT_MP3 ||
404 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
405 return true;
406
407 return false;
408}
409
410static int get_snd_codec_id(audio_format_t format)
411{
412 int id = 0;
413
414 switch (format & AUDIO_FORMAT_MAIN_MASK) {
415 case AUDIO_FORMAT_MP3:
416 id = SND_AUDIOCODEC_MP3;
417 break;
418 case AUDIO_FORMAT_AAC:
419 id = SND_AUDIOCODEC_AAC;
420 break;
421 default:
422 ALOGE("%s: Unsupported audio format", __func__);
423 }
424
425 return id;
426}
427
428/* Array to store sound devices */
429static const char * const device_table[SND_DEVICE_MAX] = {
430 [SND_DEVICE_NONE] = "none",
431 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100432 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100433 [SND_DEVICE_OUT_SPEAKER] = "speaker",
434 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
435 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100436 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100437 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100438 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100439 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100440 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100441 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100442 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
443 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100444 [SND_DEVICE_OUT_HDMI] = "hdmi",
445 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
446 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100447
448 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100449 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100450 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
451 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100452 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100453 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
454 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100455 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
456 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100457 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100458 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100459 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100460 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100461 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100462 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
463 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100464 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
465 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
466 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100467 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
468 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100469 [SND_DEVICE_IN_LOOPBACK_AEC] = "loopback-aec",
470};
471
472static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
473{
474 struct mixer_card *mixer_card;
475 struct listnode *node;
476
477 list_for_each(node, &adev->mixer_list) {
478 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
479 if (mixer_card->card == card)
480 return mixer_card;
481 }
482 return NULL;
483}
484
485static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
486{
487 struct mixer_card *mixer_card;
488 struct listnode *node;
489
490 list_for_each(node, &usecase->mixer_list) {
491 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
492 if (mixer_card->card == card)
493 return mixer_card;
494 }
495 return NULL;
496}
497
498static void free_mixer_list(struct audio_device *adev)
499{
500 struct mixer_card *mixer_card;
501 struct listnode *node;
502 struct listnode *next;
503
504 list_for_each_safe(node, next, &adev->mixer_list) {
505 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
506 list_remove(node);
507 audio_route_free(mixer_card->audio_route);
508 free(mixer_card);
509 }
510}
511
512static int mixer_init(struct audio_device *adev)
513{
514 int i;
515 int card;
516 int retry_num;
517 struct mixer *mixer;
518 struct audio_route *audio_route;
519 char mixer_path[PATH_MAX];
520 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100521 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100522
523 list_init(&adev->mixer_list);
524
525 for (i = 0; pcm_devices[i] != NULL; i++) {
526 card = pcm_devices[i]->card;
527 if (adev_get_mixer_for_card(adev, card) == NULL) {
528 retry_num = 0;
529 do {
530 mixer = mixer_open(card);
531 if (mixer == NULL) {
532 if (++retry_num > RETRY_NUMBER) {
533 ALOGE("%s unable to open the mixer for--card %d, aborting.",
534 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100535 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100536 goto error;
537 }
538 usleep(RETRY_US);
539 }
540 } while (mixer == NULL);
541
542 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
543 audio_route = audio_route_init(card, mixer_path);
544 if (!audio_route) {
545 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
546 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100547 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100548 goto error;
549 }
550 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100551 if (mixer_card == NULL) {
552 ret = -ENOMEM;
553 goto error;
554 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100555 mixer_card->card = card;
556 mixer_card->mixer = mixer;
557 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100558
559 /* Do not sleep on first enable_snd_device() */
560 mixer_card->dsp_poweroff_time.tv_sec = 1;
561 mixer_card->dsp_poweroff_time.tv_nsec = 0;
562
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100563 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
564 }
565 }
566
567 return 0;
568
569error:
570 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100571 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100572}
573
574static const char *get_snd_device_name(snd_device_t snd_device)
575{
576 const char *name = NULL;
577
Andreas Schneideradb788d2017-02-13 15:19:36 +0100578 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100579 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100580 name = device_table[snd_device];
581
582 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
583
584 return name;
585}
586
587static const char *get_snd_device_display_name(snd_device_t snd_device)
588{
589 const char *name = get_snd_device_name(snd_device);
590
591 if (name == NULL)
592 name = "SND DEVICE NOT FOUND";
593
594 return name;
595}
596
597static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
598{
599 int i;
600
601 devices &= ~AUDIO_DEVICE_BIT_IN;
602 for (i = 0; pcm_devices[i] != NULL; i++) {
603 if ((pcm_devices[i]->type == uc_type) &&
604 (devices & pcm_devices[i]->devices))
605 break;
606 }
607 return pcm_devices[i];
608}
609
610static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
611 audio_usecase_t uc_id)
612{
613 struct audio_usecase *usecase;
614 struct listnode *node;
615
616 list_for_each(node, &adev->usecase_list) {
617 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
618 if (usecase->id == uc_id)
619 return usecase;
620 }
621 return NULL;
622}
623
624static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
625 usecase_type_t type)
626{
627 struct audio_usecase *usecase;
628 struct listnode *node;
629
630 list_for_each(node, &adev->usecase_list) {
631 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
632 if (usecase->type & type)
633 return usecase;
634 }
635 return NULL;
636}
637
638/* always called with adev lock held */
639static int set_voice_volume_l(struct audio_device *adev, float volume)
640{
641 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100642
643 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100644 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100645 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100646
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100647 return err;
648}
649
650
651static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
652{
653
654 audio_mode_t mode = adev->mode;
655 snd_device_t snd_device = SND_DEVICE_NONE;
656
657 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
658 if (devices == AUDIO_DEVICE_NONE ||
659 devices & AUDIO_DEVICE_BIT_IN) {
660 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
661 goto exit;
662 }
663
664 if (mode == AUDIO_MODE_IN_CALL) {
665 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
666 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100667 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300668 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100669 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100670 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
671 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
672 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100673 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100674 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100675
676 if (voice_session_uses_wideband(adev->voice.session)) {
677 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
678 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
679 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300680 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100681 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100682 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
683 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
684 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
685 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
686 }
687 }
688
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100689 if (snd_device != SND_DEVICE_NONE) {
690 goto exit;
691 }
692 }
693
694 if (popcount(devices) == 2) {
695 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
696 AUDIO_DEVICE_OUT_SPEAKER)) {
697 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
698 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
699 AUDIO_DEVICE_OUT_SPEAKER)) {
700 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
701 } else {
702 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
703 goto exit;
704 }
705 if (snd_device != SND_DEVICE_NONE) {
706 goto exit;
707 }
708 }
709
710 if (popcount(devices) != 1) {
711 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
712 goto exit;
713 }
714
715 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
716 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
717 snd_device = SND_DEVICE_OUT_HEADPHONES;
718 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
719 snd_device = SND_DEVICE_OUT_SPEAKER;
720 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
721 snd_device = SND_DEVICE_OUT_BT_SCO;
722 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100723 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100724 } else {
725 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
726 }
727exit:
728 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
729 return snd_device;
730}
731
732static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
733{
734 audio_source_t source;
735 audio_mode_t mode = adev->mode;
736 audio_devices_t in_device;
737 audio_channel_mask_t channel_mask;
738 snd_device_t snd_device = SND_DEVICE_NONE;
739 struct stream_in *active_input = NULL;
740 struct audio_usecase *usecase;
741
742 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
743 if (usecase != NULL) {
744 active_input = (struct stream_in *)usecase->stream;
745 }
746 source = (active_input == NULL) ?
747 AUDIO_SOURCE_DEFAULT : active_input->source;
748
Andreas Schneider757e2d82017-02-10 19:28:35 +0100749 in_device = (active_input == NULL) ?
750 AUDIO_DEVICE_NONE :
751 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100752 channel_mask = (active_input == NULL) ?
753 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
754
755 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
756 __func__, out_device, in_device);
757 if (mode == AUDIO_MODE_IN_CALL) {
758 if (out_device == AUDIO_DEVICE_NONE) {
759 ALOGE("%s: No output device set for voice call", __func__);
760 goto exit;
761 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100762
Andreas Schneider82f32482017-02-06 09:00:48 +0100763 snd_device = SND_DEVICE_IN_VOICE_MIC;
764 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100765 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100766 }
767
768 if (voice_session_uses_twomic(adev->voice.session)) {
769 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
770 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
771 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
772 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
773 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
774 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100775 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100776
777 if (voice_session_uses_wideband(adev->voice.session)) {
778 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
779 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
780 }
781
782 if (voice_session_uses_twomic(adev->voice.session)) {
783 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
784 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
785 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
786 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
787 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
788 }
789 }
790 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100791
792 /* BT SCO */
793 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
794 snd_device = SND_DEVICE_IN_VOICE_MIC;
795
796 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300797 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100798 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300799 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100800 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300801 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100802 } else if (voice_session_uses_twomic(adev->voice.session)) {
803 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
804 }
805 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100806 } else if (source == AUDIO_SOURCE_CAMCORDER) {
807 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
808 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
809 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
810 }
811 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
812 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100813 if (snd_device == SND_DEVICE_NONE) {
814 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
815 }
816 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
817 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
818 }
819 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
820 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
821 in_device = AUDIO_DEVICE_IN_BACK_MIC;
822 if (active_input) {
823 if (active_input->enable_aec) {
824 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
825 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
826 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
827 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
828 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
829 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100830 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100831 }
832 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
833 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
834 }
835 }
836 /* TODO: set echo reference */
837 }
838 } else if (source == AUDIO_SOURCE_DEFAULT) {
839 goto exit;
840 }
841
842
843 if (snd_device != SND_DEVICE_NONE) {
844 goto exit;
845 }
846
847 if (in_device != AUDIO_DEVICE_NONE &&
848 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
849 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
850 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100851 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100852 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
853 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
854 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
855 snd_device = SND_DEVICE_IN_HEADSET_MIC;
856 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
857 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
858 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
859 snd_device = SND_DEVICE_IN_HDMI_MIC;
860 } else {
861 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100862 ALOGW("%s: Using default earpiece-mic", __func__);
863 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100864 }
865 } else {
866 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100867 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100868 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
869 snd_device = SND_DEVICE_IN_HEADSET_MIC;
870 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
871 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
872 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100873 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100874 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
875 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
876 } else {
877 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100878 ALOGW("%s: Using default earpiece-mic", __func__);
879 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100880 }
881 }
882exit:
883 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
884 return snd_device;
885}
886
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100887#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100888static int set_hdmi_channels(struct audio_device *adev, int channel_count)
889{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100890 (void)adev;
891 (void)channel_count;
892 /* TODO */
893
894 return 0;
895}
896
897static int edid_get_max_channels(struct audio_device *adev)
898{
899 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100900 (void)adev;
901
902 /* TODO */
903 return max_channels;
904}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100905#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100906
907/* Delay in Us */
908static int64_t render_latency(audio_usecase_t usecase)
909{
910 (void)usecase;
911 /* TODO */
912 return 0;
913}
914
915static int enable_snd_device(struct audio_device *adev,
916 struct audio_usecase *uc_info,
917 snd_device_t snd_device,
918 bool update_mixer)
919{
920 struct mixer_card *mixer_card;
921 struct listnode *node;
922 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100923#ifdef DSP_POWEROFF_DELAY
924 struct timespec activation_time;
925 struct timespec elapsed_time;
926#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100927
928 if (snd_device_name == NULL)
929 return -EINVAL;
930
931 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
932 ALOGV("Request to enable combo device: enable individual devices\n");
933 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
934 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
935 return 0;
936 }
937 adev->snd_dev_ref_cnt[snd_device]++;
938 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
939 ALOGV("%s: snd_device(%d: %s) is already active",
940 __func__, snd_device, snd_device_name);
941 return 0;
942 }
943
944 ALOGV("%s: snd_device(%d: %s)", __func__,
945 snd_device, snd_device_name);
946
947 list_for_each(node, &uc_info->mixer_list) {
948 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100949
950#ifdef DSP_POWEROFF_DELAY
951 clock_gettime(CLOCK_MONOTONIC, &activation_time);
952
Andreas Schneider58735a92017-02-13 16:48:17 +0100953 elapsed_time = time_spec_diff(activation_time,
954 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100955 if (elapsed_time.tv_sec == 0) {
956 long elapsed_usec = elapsed_time.tv_nsec / 1000;
957
958 if (elapsed_usec < DSP_POWEROFF_DELAY) {
959 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
960 }
961 }
962 update_mixer = true;
963#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200964
965 amplifier_enable_devices(snd_device, true);
966
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100967 audio_route_apply_path(mixer_card->audio_route, snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100968 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100969 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +0100970 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100971 }
972
973 return 0;
974}
975
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100976int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100977 struct audio_usecase *uc_info,
978 snd_device_t snd_device,
979 bool update_mixer)
980{
981 struct mixer_card *mixer_card;
982 struct listnode *node;
983 const char *snd_device_name = get_snd_device_name(snd_device);
984
985 if (snd_device_name == NULL)
986 return -EINVAL;
987
988 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
989 ALOGV("Request to disable combo device: disable individual devices\n");
990 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
991 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
992 return 0;
993 }
994
995 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
996 ALOGE("%s: device ref cnt is already 0", __func__);
997 return -EINVAL;
998 }
999 adev->snd_dev_ref_cnt[snd_device]--;
1000 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
1001 ALOGV("%s: snd_device(%d: %s)", __func__,
1002 snd_device, snd_device_name);
1003 list_for_each(node, &uc_info->mixer_list) {
1004 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +01001005#ifdef DSP_POWEROFF_DELAY
1006 update_mixer = true;
1007#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001008 audio_route_reset_path(mixer_card->audio_route, snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +01001009 if (update_mixer) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001010 audio_route_update_mixer(mixer_card->audio_route);
Andreas Schneider759368f2017-02-02 16:11:14 +01001011 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001012
1013 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +01001014#ifdef DSP_POWEROFF_DELAY
1015 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
1016#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001017 }
1018 }
1019 return 0;
1020}
1021
1022static int select_devices(struct audio_device *adev,
1023 audio_usecase_t uc_id)
1024{
1025 snd_device_t out_snd_device = SND_DEVICE_NONE;
1026 snd_device_t in_snd_device = SND_DEVICE_NONE;
1027 struct audio_usecase *usecase = NULL;
1028 struct audio_usecase *vc_usecase = NULL;
1029 struct listnode *node;
1030 struct stream_in *active_input = NULL;
1031 struct stream_out *active_out;
1032 struct mixer_card *mixer_card;
1033
1034 ALOGV("%s: usecase(%d)", __func__, uc_id);
1035
1036 if (uc_id == USECASE_AUDIO_CAPTURE_HOTWORD)
1037 return 0;
1038
1039 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1040 if (usecase != NULL) {
1041 active_input = (struct stream_in *)usecase->stream;
1042 }
1043
1044 usecase = get_usecase_from_id(adev, uc_id);
1045 if (usecase == NULL) {
1046 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1047 return -EINVAL;
1048 }
1049 active_out = (struct stream_out *)usecase->stream;
1050
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001051
1052 /*
1053 * If the voice call is active, use the sound devices of voice call usecase
1054 * so that it would not result any device switch. All the usecases will
1055 * be switched to new device when select_devices() is called for voice call
1056 * usecase.
1057 */
1058 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1059 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1060 if (vc_usecase == NULL) {
1061 ALOGE("%s: Could not find the voice call usecase", __func__);
1062 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001063 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1064 get_snd_device_display_name(vc_usecase->out_snd_device),
1065 get_snd_device_display_name(vc_usecase->in_snd_device));
1066 usecase->devices = vc_usecase->devices;
1067 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001068 }
1069 }
1070
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001071 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001072 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001073 prepare_voice_session(adev->voice.session, active_out->devices);
1074 out_snd_device = get_output_snd_device(adev, active_out->devices);
1075 in_snd_device = get_input_snd_device(adev, active_out->devices);
1076 } else if (usecase->type == PCM_PLAYBACK) {
1077 usecase->devices = active_out->devices;
1078 in_snd_device = SND_DEVICE_NONE;
1079 if (out_snd_device == SND_DEVICE_NONE) {
1080 out_snd_device = get_output_snd_device(adev, active_out->devices);
1081 if (active_out == adev->primary_output &&
1082 active_input &&
1083 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1084 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001085 }
1086 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001087 } else if (usecase->type == PCM_CAPTURE) {
1088 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1089 out_snd_device = SND_DEVICE_NONE;
1090 if (in_snd_device == SND_DEVICE_NONE) {
1091 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1092 adev->primary_output && !adev->primary_output->standby) {
1093 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1094 } else {
1095 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001096 }
1097 }
1098 }
1099
1100 if (out_snd_device == usecase->out_snd_device &&
1101 in_snd_device == usecase->in_snd_device) {
1102 return 0;
1103 }
1104
1105 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1106 out_snd_device, get_snd_device_display_name(out_snd_device),
1107 in_snd_device, get_snd_device_display_name(in_snd_device));
1108
1109
1110 /* Disable current sound devices */
1111 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001112 disable_snd_device(adev, usecase, usecase->out_snd_device, false);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001113 }
1114
1115 if (usecase->in_snd_device != SND_DEVICE_NONE) {
1116 disable_snd_device(adev, usecase, usecase->in_snd_device, false);
1117 }
1118
1119 /* Enable new sound devices */
1120 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001121 /* We need to update the audio path if we switch the out devices */
1122 if (adev->voice.in_call) {
1123 set_voice_session_audio_path(adev->voice.session);
1124 }
1125
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001126 enable_snd_device(adev, usecase, out_snd_device, false);
1127 }
1128
1129 if (in_snd_device != SND_DEVICE_NONE) {
1130 enable_snd_device(adev, usecase, in_snd_device, false);
1131 }
1132
1133 list_for_each(node, &usecase->mixer_list) {
1134 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
1135 audio_route_update_mixer(mixer_card->audio_route);
1136 }
1137
1138 usecase->in_snd_device = in_snd_device;
1139 usecase->out_snd_device = out_snd_device;
1140
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001141 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1142 amplifier_set_input_devices(in_snd_device);
1143 amplifier_set_output_devices(out_snd_device);
1144
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001145 return 0;
1146}
1147
1148
1149static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1150static int do_in_standby_l(struct stream_in *in);
1151
1152#ifdef PREPROCESSING_ENABLED
1153static void get_capture_reference_delay(struct stream_in *in,
1154 size_t frames __unused,
1155 struct echo_reference_buffer *buffer)
1156{
1157 ALOGVV("%s: enter:)", __func__);
1158
1159 /* read frames available in kernel driver buffer */
1160 unsigned int kernel_frames;
1161 struct timespec tstamp;
1162 long buf_delay;
1163 long kernel_delay;
1164 long delay_ns;
1165 struct pcm_device *ref_device;
1166 long rsmp_delay = 0;
1167
1168 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1169 struct pcm_device, stream_list_node);
1170
1171 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1172 buffer->time_stamp.tv_sec = 0;
1173 buffer->time_stamp.tv_nsec = 0;
1174 buffer->delay_ns = 0;
1175 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1176 return;
1177 }
1178
1179 /* adjust render time stamp with delay added by current driver buffer.
1180 * Add the duration of current frame as we want the render time of the last
1181 * sample being written. */
1182
1183 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1184
1185 buffer->time_stamp = tstamp;
1186 buffer->delay_ns = kernel_delay;
1187
1188 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1189 " delay_ns: [%d] , frames:[%zd]",
1190 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1191}
1192
1193static void get_capture_delay(struct stream_in *in,
1194 size_t frames __unused,
1195 struct echo_reference_buffer *buffer)
1196{
1197 ALOGVV("%s: enter:)", __func__);
1198 /* read frames available in kernel driver buffer */
1199 unsigned int kernel_frames;
1200 struct timespec tstamp;
1201 long buf_delay;
1202 long rsmp_delay;
1203 long kernel_delay;
1204 long delay_ns;
1205 struct pcm_device *pcm_device;
1206
1207 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1208 struct pcm_device, stream_list_node);
1209
1210 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1211 buffer->time_stamp.tv_sec = 0;
1212 buffer->time_stamp.tv_nsec = 0;
1213 buffer->delay_ns = 0;
1214 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1215 return;
1216 }
1217
1218 /* read frames available in audio HAL input buffer
1219 * add number of frames being read as we want the capture time of first sample
1220 * in current buffer */
1221 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1222 * at requested sampling rate */
1223 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1224 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1225
1226 /* add delay introduced by resampler */
1227 rsmp_delay = 0;
1228 if (in->resampler) {
1229 rsmp_delay = in->resampler->delay_ns(in->resampler);
1230 }
1231
1232 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1233
1234 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1235
1236 buffer->time_stamp = tstamp;
1237 buffer->delay_ns = delay_ns;
1238 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1239 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1240 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1241 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1242 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1243 in->read_buf_frames, in->proc_buf_frames, frames);
1244}
1245
1246static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1247{
1248 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1249 struct echo_reference_buffer b;
1250 b.delay_ns = 0;
1251 struct pcm_device *pcm_device;
1252
1253 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1254 struct pcm_device, stream_list_node);
1255
1256 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1257 "b.frame_count = [%zd]",
1258 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1259 if (in->ref_buf_frames < frames) {
1260 if (in->ref_buf_size < frames) {
1261 in->ref_buf_size = frames;
1262 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1263 ALOG_ASSERT((in->ref_buf != NULL),
1264 "update_echo_reference() failed to reallocate ref_buf");
1265 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1266 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1267 }
1268 b.frame_count = frames - in->ref_buf_frames;
1269 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1270
1271 get_capture_delay(in, frames, &b);
1272
1273 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1274 {
1275 in->ref_buf_frames += b.frame_count;
1276 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1277 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1278 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1279 }
1280 } else
1281 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1282 return b.delay_ns;
1283}
1284
1285static int set_preprocessor_param(effect_handle_t handle,
1286 effect_param_t *param)
1287{
1288 uint32_t size = sizeof(int);
1289 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1290 param->vsize;
1291
1292 int status = (*handle)->command(handle,
1293 EFFECT_CMD_SET_PARAM,
1294 sizeof (effect_param_t) + psize,
1295 param,
1296 &size,
1297 &param->status);
1298 if (status == 0)
1299 status = param->status;
1300
1301 return status;
1302}
1303
1304static int set_preprocessor_echo_delay(effect_handle_t handle,
1305 int32_t delay_us)
1306{
1307 struct {
1308 effect_param_t param;
1309 uint32_t data_0;
1310 int32_t data_1;
1311 } buf;
1312 memset(&buf, 0, sizeof(buf));
1313
1314 buf.param.psize = sizeof(uint32_t);
1315 buf.param.vsize = sizeof(uint32_t);
1316 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1317 buf.data_1 = delay_us;
1318
1319 return set_preprocessor_param(handle, &buf.param);
1320}
1321
1322static void push_echo_reference(struct stream_in *in, size_t frames)
1323{
1324 ALOGVV("%s: enter:)", __func__);
1325 /* read frames from echo reference buffer and update echo delay
1326 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1327
1328 int32_t delay_us = update_echo_reference(in, frames)/1000;
1329 int32_t size_in_bytes = 0;
1330 int i;
1331 audio_buffer_t buf;
1332
1333 if (in->ref_buf_frames < frames)
1334 frames = in->ref_buf_frames;
1335
1336 buf.frameCount = frames;
1337 buf.raw = in->ref_buf;
1338
1339 for (i = 0; i < in->num_preprocessors; i++) {
1340 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1341 continue;
1342 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1343 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1344 &buf,
1345 NULL);
1346 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1347 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1348 }
1349
1350 in->ref_buf_frames -= buf.frameCount;
1351 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1352 __func__, in->ref_buf_frames, in->config.channels);
1353 if (in->ref_buf_frames) {
1354 memcpy(in->ref_buf,
1355 in->ref_buf + buf.frameCount * in->config.channels,
1356 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1357 }
1358}
1359
1360static void put_echo_reference(struct audio_device *adev,
1361 struct echo_reference_itfe *reference)
1362{
1363 ALOGV("%s: enter:)", __func__);
1364 int32_t prev_generation = adev->echo_reference_generation;
1365 struct stream_out *out = adev->primary_output;
1366
1367 if (adev->echo_reference != NULL &&
1368 reference == adev->echo_reference) {
1369 /* echo reference is taken from the low latency output stream used
1370 * for voice use cases */
1371 adev->echo_reference = NULL;
1372 android_atomic_inc(&adev->echo_reference_generation);
1373 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1374 // if the primary output is in standby or did not pick the echo reference yet
1375 // we can safely get rid of it here.
1376 // otherwise, out_write() or out_standby() will detect the change in echo reference
1377 // generation and release the echo reference owned by the stream.
1378 if ((out->echo_reference_generation != prev_generation) || out->standby)
1379 release_echo_reference(reference);
1380 } else {
1381 release_echo_reference(reference);
1382 }
1383 ALOGV("release_echo_reference");
1384 }
1385}
1386
1387static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1388 audio_format_t format __unused,
1389 uint32_t channel_count,
1390 uint32_t sampling_rate)
1391{
1392 ALOGV("%s: enter:)", __func__);
1393 put_echo_reference(adev, adev->echo_reference);
1394 /* echo reference is taken from the low latency output stream used
1395 * for voice use cases */
1396 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1397 !adev->primary_output->standby) {
1398 struct audio_stream *stream =
1399 &adev->primary_output->stream.common;
1400 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1401 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1402 ALOGV("Calling create_echo_reference");
1403 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1404 channel_count,
1405 sampling_rate,
1406 AUDIO_FORMAT_PCM_16_BIT,
1407 wr_channel_count,
1408 wr_sampling_rate,
1409 &adev->echo_reference);
1410 if (status == 0)
1411 android_atomic_inc(&adev->echo_reference_generation);
1412 }
1413 return adev->echo_reference;
1414}
1415
1416#ifdef HW_AEC_LOOPBACK
1417static int get_hw_echo_reference(struct stream_in *in)
1418{
1419 struct pcm_device_profile *ref_pcm_profile;
1420 struct pcm_device *ref_device;
1421 struct audio_device *adev = in->dev;
1422
1423 in->hw_echo_reference = false;
1424
1425 if (adev->primary_output!= NULL &&
1426 !adev->primary_output->standby &&
1427 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1428 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1429 struct audio_stream *stream = &adev->primary_output->stream.common;
1430
1431 // TODO: currently there is no low latency mode for aec reference.
1432 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1433 if (ref_pcm_profile == NULL) {
1434 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1435 __func__, pcm_device_capture_loopback_aec.devices);
1436 return -EINVAL;
1437 }
1438
1439 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001440 if (ref_device == NULL) {
1441 return -ENOMEM;
1442 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001443 ref_device->pcm_profile = ref_pcm_profile;
1444
1445 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1446 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1447
1448 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1449 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1450 pcm_close(ref_device->pcm);
1451 ref_device->pcm = NULL;
1452 return -EIO;
1453 }
1454 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1455
1456 in->hw_echo_reference = true;
1457
1458 ALOGV("%s: hw_echo_reference is true", __func__);
1459 }
1460
1461 return 0;
1462}
1463#endif
1464
1465static int get_playback_delay(struct stream_out *out,
1466 size_t frames,
1467 struct echo_reference_buffer *buffer)
1468{
1469 unsigned int kernel_frames;
1470 int status;
1471 int primary_pcm = 0;
1472 struct pcm_device *pcm_device;
1473
1474 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1475 struct pcm_device, stream_list_node);
1476
1477 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1478 if (status < 0) {
1479 buffer->time_stamp.tv_sec = 0;
1480 buffer->time_stamp.tv_nsec = 0;
1481 buffer->delay_ns = 0;
1482 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1483 "setting playbackTimestamp to 0");
1484 return status;
1485 }
1486
1487 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1488
1489 /* adjust render time stamp with delay added by current driver buffer.
1490 * Add the duration of current frame as we want the render time of the last
1491 * sample being written. */
1492 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1493 out->config.rate);
1494 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1495 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1496
1497 return 0;
1498}
1499
1500#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1501 do { \
1502 if (fct_status != 0) \
1503 status = fct_status; \
1504 else if (cmd_status != 0) \
1505 status = cmd_status; \
1506 } while(0)
1507
1508static int in_configure_reverse(struct stream_in *in)
1509{
1510 int32_t cmd_status;
1511 uint32_t size = sizeof(int);
1512 effect_config_t config;
1513 int32_t status = 0;
1514 int32_t fct_status = 0;
1515 int i;
1516 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1517 if (in->num_preprocessors > 0) {
1518 config.inputCfg.channels = in->main_channels;
1519 config.outputCfg.channels = in->main_channels;
1520 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1521 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1522 config.inputCfg.samplingRate = in->requested_rate;
1523 config.outputCfg.samplingRate = in->requested_rate;
1524 config.inputCfg.mask =
1525 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1526 config.outputCfg.mask =
1527 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1528
1529 for (i = 0; i < in->num_preprocessors; i++)
1530 {
1531 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1532 continue;
1533 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1534 in->preprocessors[i].effect_itfe,
1535 EFFECT_CMD_SET_CONFIG_REVERSE,
1536 sizeof(effect_config_t),
1537 &config,
1538 &size,
1539 &cmd_status);
1540 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1541 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1542 }
1543 }
1544 return status;
1545}
1546
1547#define MAX_NUM_CHANNEL_CONFIGS 10
1548
1549static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1550 struct effect_info_s *effect_info)
1551{
1552 /* size and format of the cmd are defined in hardware/audio_effect.h */
1553 effect_handle_t effect = effect_info->effect_itfe;
1554 uint32_t cmd_size = 2 * sizeof(uint32_t);
1555 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1556 /* reply = status + number of configs (n) + n x channel_config_t */
1557 uint32_t reply_size =
1558 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1559 int32_t reply[reply_size];
1560 int32_t cmd_status;
1561
1562 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1563 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1564 ALOG_ASSERT((effect_info->channel_configs == NULL),
1565 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1566
1567 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1568 * This error will be interpreted as if the effect supports the main_channels but does not
1569 * support any aux_channels */
1570 cmd_status = (*effect)->command(effect,
1571 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1572 cmd_size,
1573 (void*)&cmd,
1574 &reply_size,
1575 (void*)&reply);
1576
1577 if (cmd_status != 0) {
1578 ALOGV("in_read_audio_effect_channel_configs(): "
1579 "fx->command returned %d", cmd_status);
1580 return;
1581 }
1582
1583 if (reply[0] != 0) {
1584 ALOGW("in_read_audio_effect_channel_configs(): "
1585 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1586 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1587 return;
1588 }
1589
1590 /* the feature is not supported */
1591 ALOGV("in_read_audio_effect_channel_configs()(): "
1592 "Feature supported and adding %d channel configs to the list", reply[1]);
1593 effect_info->num_channel_configs = reply[1];
1594 effect_info->channel_configs =
1595 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1596 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1597}
1598
1599
1600#define NUM_IN_AUX_CNL_CONFIGS 2
1601static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1602 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1603 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1604};
1605static uint32_t in_get_aux_channels(struct stream_in *in)
1606{
1607 int i;
1608 channel_config_t new_chcfg = {0, 0};
1609
1610 if (in->num_preprocessors == 0)
1611 return 0;
1612
1613 /* do not enable dual mic configurations when capturing from other microphones than
1614 * main or sub */
1615 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1616 return 0;
1617
1618 /* retain most complex aux channels configuration compatible with requested main channels and
1619 * supported by audio driver and all pre processors */
1620 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1621 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1622 if (cur_chcfg->main_channels == in->main_channels) {
1623 size_t match_cnt;
1624 size_t idx_preproc;
1625 for (idx_preproc = 0, match_cnt = 0;
1626 /* no need to continue if at least one preprocessor doesn't match */
1627 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1628 idx_preproc++) {
1629 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1630 size_t idx_chcfg;
1631
1632 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1633 if (memcmp(effect_info->channel_configs + idx_chcfg,
1634 cur_chcfg,
1635 sizeof(channel_config_t)) == 0) {
1636 match_cnt++;
1637 break;
1638 }
1639 }
1640 }
1641 /* if all preprocessors match, we have a candidate */
1642 if (match_cnt == (size_t)in->num_preprocessors) {
1643 /* retain most complex aux channels configuration */
1644 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1645 new_chcfg = *cur_chcfg;
1646 }
1647 }
1648 }
1649 }
1650
1651 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1652
1653 return new_chcfg.aux_channels;
1654}
1655
1656static int in_configure_effect_channels(effect_handle_t effect,
1657 channel_config_t *channel_config)
1658{
1659 int status = 0;
1660 int fct_status;
1661 int32_t cmd_status;
1662 uint32_t reply_size;
1663 effect_config_t config;
1664 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1665
1666 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1667 channel_config->main_channels,
1668 channel_config->aux_channels);
1669
1670 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1671 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1672 reply_size = sizeof(effect_config_t);
1673 fct_status = (*effect)->command(effect,
1674 EFFECT_CMD_GET_CONFIG,
1675 0,
1676 NULL,
1677 &reply_size,
1678 &config);
1679 if (fct_status != 0) {
1680 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1681 return fct_status;
1682 }
1683
1684 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1685 config.outputCfg.channels = config.inputCfg.channels;
1686 reply_size = sizeof(uint32_t);
1687 fct_status = (*effect)->command(effect,
1688 EFFECT_CMD_SET_CONFIG,
1689 sizeof(effect_config_t),
1690 &config,
1691 &reply_size,
1692 &cmd_status);
1693 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1694
1695 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1696 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1697 reply_size = sizeof(uint32_t);
1698 fct_status = (*effect)->command(effect,
1699 EFFECT_CMD_SET_FEATURE_CONFIG,
1700 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1701 cmd,
1702 &reply_size,
1703 &cmd_status);
1704 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1705
1706 /* some implementations need to be re-enabled after a config change */
1707 reply_size = sizeof(uint32_t);
1708 fct_status = (*effect)->command(effect,
1709 EFFECT_CMD_ENABLE,
1710 0,
1711 NULL,
1712 &reply_size,
1713 &cmd_status);
1714 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1715
1716 return status;
1717}
1718
1719static int in_reconfigure_channels(struct stream_in *in,
1720 effect_handle_t effect,
1721 channel_config_t *channel_config,
1722 bool config_changed) {
1723
1724 int status = 0;
1725
1726 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1727 config_changed, effect);
1728
1729 /* if config changed, reconfigure all previously added effects */
1730 if (config_changed) {
1731 int i;
1732 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1733 for (i = 0; i < in->num_preprocessors; i++)
1734 {
1735 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1736 channel_config);
1737 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1738 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1739 if (cur_status != 0) {
1740 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1741 "%d with channels: [%04x][%04x]",
1742 cur_status,
1743 i,
1744 channel_config->main_channels,
1745 channel_config->aux_channels);
1746 status = cur_status;
1747 }
1748 }
1749 } else if (effect != NULL && channel_config->aux_channels) {
1750 /* if aux channels config did not change but aux channels are present,
1751 * we still need to configure the effect being added */
1752 status = in_configure_effect_channels(effect, channel_config);
1753 }
1754 return status;
1755}
1756
1757static void in_update_aux_channels(struct stream_in *in,
1758 effect_handle_t effect)
1759{
1760 uint32_t aux_channels;
1761 channel_config_t channel_config;
1762 int status;
1763
1764 aux_channels = in_get_aux_channels(in);
1765
1766 channel_config.main_channels = in->main_channels;
1767 channel_config.aux_channels = aux_channels;
1768 status = in_reconfigure_channels(in,
1769 effect,
1770 &channel_config,
1771 (aux_channels != in->aux_channels));
1772
1773 if (status != 0) {
1774 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1775 /* resetting aux channels configuration */
1776 aux_channels = 0;
1777 channel_config.aux_channels = 0;
1778 in_reconfigure_channels(in, effect, &channel_config, true);
1779 }
1780 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1781 if (in->aux_channels != aux_channels) {
1782 in->aux_channels_changed = true;
1783 in->aux_channels = aux_channels;
1784 do_in_standby_l(in);
1785 }
1786}
1787#endif
1788
1789/* This function reads PCM data and:
1790 * - resample if needed
1791 * - process if pre-processors are attached
1792 * - discard unwanted channels
1793 */
1794static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1795{
1796 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001797 size_t src_channels = in->config.channels;
1798 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1799 int i;
1800 void *proc_buf_out;
1801 struct pcm_device *pcm_device;
1802 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1803#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001804 audio_buffer_t in_buf;
1805 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001806 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1807#endif
1808
1809 /* Additional channels might be added on top of main_channels:
1810 * - aux_channels (by processing effects)
1811 * - extra channels due to HW limitations
1812 * In case of additional channels, we cannot work inplace
1813 */
1814 if (has_additional_channels)
1815 proc_buf_out = in->proc_buf_out;
1816 else
1817 proc_buf_out = buffer;
1818
1819 if (list_empty(&in->pcm_dev_list)) {
1820 ALOGE("%s: pcm device list empty", __func__);
1821 return -EINVAL;
1822 }
1823
1824 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1825 struct pcm_device, stream_list_node);
1826
1827#ifdef PREPROCESSING_ENABLED
1828 if (has_processing) {
1829 /* since all the processing below is done in frames and using the config.channels
1830 * as the number of channels, no changes is required in case aux_channels are present */
1831 while (frames_wr < frames) {
1832 /* first reload enough frames at the end of process input buffer */
1833 if (in->proc_buf_frames < (size_t)frames) {
1834 ssize_t frames_rd;
1835 if (in->proc_buf_size < (size_t)frames) {
1836 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1837 in->proc_buf_size = (size_t)frames;
1838 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1839 ALOG_ASSERT((in->proc_buf_in != NULL),
1840 "process_frames() failed to reallocate proc_buf_in");
1841 if (has_additional_channels) {
1842 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1843 ALOG_ASSERT((in->proc_buf_out != NULL),
1844 "process_frames() failed to reallocate proc_buf_out");
1845 proc_buf_out = in->proc_buf_out;
1846 }
1847 }
1848 frames_rd = read_frames(in,
1849 in->proc_buf_in +
1850 in->proc_buf_frames * in->config.channels,
1851 frames - in->proc_buf_frames);
1852 if (frames_rd < 0) {
1853 /* Return error code */
1854 frames_wr = frames_rd;
1855 break;
1856 }
1857 in->proc_buf_frames += frames_rd;
1858 }
1859
1860 if (in->echo_reference != NULL) {
1861 push_echo_reference(in, in->proc_buf_frames);
1862 }
1863
1864 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1865 * the maximum number of frames to be consumed and produced by process() */
1866 in_buf.frameCount = in->proc_buf_frames;
1867 in_buf.s16 = in->proc_buf_in;
1868 out_buf.frameCount = frames - frames_wr;
1869 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1870
1871 /* FIXME: this works because of current pre processing library implementation that
1872 * does the actual process only when the last enabled effect process is called.
1873 * The generic solution is to have an output buffer for each effect and pass it as
1874 * input to the next.
1875 */
1876 for (i = 0; i < in->num_preprocessors; i++) {
1877 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1878 &in_buf,
1879 &out_buf);
1880 }
1881
1882 /* process() has updated the number of frames consumed and produced in
1883 * in_buf.frameCount and out_buf.frameCount respectively
1884 * move remaining frames to the beginning of in->proc_buf_in */
1885 in->proc_buf_frames -= in_buf.frameCount;
1886
1887 if (in->proc_buf_frames) {
1888 memcpy(in->proc_buf_in,
1889 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1890 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1891 }
1892
1893 /* if not enough frames were passed to process(), read more and retry. */
1894 if (out_buf.frameCount == 0) {
1895 ALOGW("No frames produced by preproc");
1896 continue;
1897 }
1898
1899 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1900 frames_wr += out_buf.frameCount;
1901 } else {
1902 /* The effect does not comply to the API. In theory, we should never end up here! */
1903 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1904 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1905 frames_wr = frames;
1906 }
1907 }
1908 }
1909 else
1910#endif //PREPROCESSING_ENABLED
1911 {
1912 /* No processing effects attached */
1913 if (has_additional_channels) {
1914 /* With additional channels, we cannot use original buffer */
1915 if (in->proc_buf_size < (size_t)frames) {
1916 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1917 in->proc_buf_size = (size_t)frames;
1918 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1919 ALOG_ASSERT((in->proc_buf_out != NULL),
1920 "process_frames() failed to reallocate proc_buf_out");
1921 proc_buf_out = in->proc_buf_out;
1922 }
1923 }
1924 frames_wr = read_frames(in, proc_buf_out, frames);
1925 }
1926
1927 /* Remove all additional channels that have been added on top of main_channels:
1928 * - aux_channels
1929 * - extra channels from HW due to HW limitations
1930 * Assumption is made that the channels are interleaved and that the main
1931 * channels are first. */
1932
1933 if (has_additional_channels)
1934 {
1935 int16_t* src_buffer = (int16_t *)proc_buf_out;
1936 int16_t* dst_buffer = (int16_t *)buffer;
1937
1938 if (dst_channels == 1) {
1939 for (i = frames_wr; i > 0; i--)
1940 {
1941 *dst_buffer++ = *src_buffer;
1942 src_buffer += src_channels;
1943 }
1944 } else {
1945 for (i = frames_wr; i > 0; i--)
1946 {
1947 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1948 dst_buffer += dst_channels;
1949 src_buffer += src_channels;
1950 }
1951 }
1952 }
1953
1954 return frames_wr;
1955}
1956
1957static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1958 struct resampler_buffer* buffer)
1959{
1960 struct stream_in *in;
1961 struct pcm_device *pcm_device;
1962
1963 if (buffer_provider == NULL || buffer == NULL)
1964 return -EINVAL;
1965
1966 in = (struct stream_in *)((char *)buffer_provider -
1967 offsetof(struct stream_in, buf_provider));
1968
1969 if (list_empty(&in->pcm_dev_list)) {
1970 buffer->raw = NULL;
1971 buffer->frame_count = 0;
1972 in->read_status = -ENODEV;
1973 return -ENODEV;
1974 }
1975
1976 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1977 struct pcm_device, stream_list_node);
1978
1979 if (in->read_buf_frames == 0) {
1980 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1981 if (in->read_buf_size < in->config.period_size) {
1982 in->read_buf_size = in->config.period_size;
1983 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1984 ALOG_ASSERT((in->read_buf != NULL),
1985 "get_next_buffer() failed to reallocate read_buf");
1986 }
1987
1988 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1989
1990 if (in->read_status != 0) {
1991 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1992 buffer->raw = NULL;
1993 buffer->frame_count = 0;
1994 return in->read_status;
1995 }
1996 in->read_buf_frames = in->config.period_size;
1997
1998#ifdef PREPROCESSING_ENABLED
1999#ifdef HW_AEC_LOOPBACK
2000 if (in->hw_echo_reference) {
2001 struct pcm_device *temp_device = NULL;
2002 struct pcm_device *ref_device = NULL;
2003 struct listnode *node = NULL;
2004 struct echo_reference_buffer b;
2005 size_t size_hw_ref_bytes;
2006 size_t size_hw_ref_frames;
2007 int read_status = 0;
2008
2009 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
2010 struct pcm_device, stream_list_node);
2011 list_for_each(node, &in->pcm_dev_list) {
2012 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
2013 if (temp_device->pcm_profile->id == 1) {
2014 ref_device = temp_device;
2015 break;
2016 }
2017 }
2018 if (ref_device) {
2019 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
2020 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
2021 if (in->hw_ref_buf_size < size_hw_ref_frames) {
2022 in->hw_ref_buf_size = size_hw_ref_frames;
2023 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2024 ALOG_ASSERT((in->hw_ref_buf != NULL),
2025 "get_next_buffer() failed to reallocate hw_ref_buf");
2026 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2027 in->hw_ref_buf, size_hw_ref_bytes);
2028 }
2029
2030 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2031 if (read_status != 0) {
2032 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2033 b.raw = NULL;
2034 b.frame_count = 0;
2035 }
2036 else {
2037 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2038 b.raw = (void *)in->hw_ref_buf;
2039 b.frame_count = size_hw_ref_frames;
2040 if (b.delay_ns != 0)
2041 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2042 in->echo_reference->write(in->echo_reference, &b);
2043 }
2044 }
2045 }
2046#endif // HW_AEC_LOOPBACK
2047#endif // PREPROCESSING_ENABLED
2048 }
2049
2050 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2051 in->read_buf_frames : buffer->frame_count;
2052 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2053 in->config.channels;
2054 return in->read_status;
2055}
2056
2057static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2058 struct resampler_buffer* buffer)
2059{
2060 struct stream_in *in;
2061
2062 if (buffer_provider == NULL || buffer == NULL)
2063 return;
2064
2065 in = (struct stream_in *)((char *)buffer_provider -
2066 offsetof(struct stream_in, buf_provider));
2067
2068 in->read_buf_frames -= buffer->frame_count;
2069}
2070
2071/* read_frames() reads frames from kernel driver, down samples to capture rate
2072 * if necessary and output the number of frames requested to the buffer specified */
2073static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2074{
2075 ssize_t frames_wr = 0;
2076
2077 struct pcm_device *pcm_device;
2078
2079 if (list_empty(&in->pcm_dev_list)) {
2080 ALOGE("%s: pcm device list empty", __func__);
2081 return -EINVAL;
2082 }
2083
2084 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2085 struct pcm_device, stream_list_node);
2086
2087 while (frames_wr < frames) {
2088 size_t frames_rd = frames - frames_wr;
2089 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2090 __func__,frames_rd,frames_wr,in->config.channels);
2091 if (in->resampler != NULL) {
2092 in->resampler->resample_from_provider(in->resampler,
2093 (int16_t *)((char *)buffer +
2094 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2095 &frames_rd);
2096 } else {
2097 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002098 .raw = NULL,
2099 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002100 };
2101 get_next_buffer(&in->buf_provider, &buf);
2102 if (buf.raw != NULL) {
2103 memcpy((char *)buffer +
2104 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2105 buf.raw,
2106 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2107 frames_rd = buf.frame_count;
2108 }
2109 release_buffer(&in->buf_provider, &buf);
2110 }
2111 /* in->read_status is updated by getNextBuffer() also called by
2112 * in->resampler->resample_from_provider() */
2113 if (in->read_status != 0)
2114 return in->read_status;
2115
2116 frames_wr += frames_rd;
2117 }
2118 return frames_wr;
2119}
2120
2121static int in_release_pcm_devices(struct stream_in *in)
2122{
2123 struct pcm_device *pcm_device;
2124 struct listnode *node;
2125 struct listnode *next;
2126
2127 list_for_each_safe(node, next, &in->pcm_dev_list) {
2128 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2129 list_remove(node);
2130 free(pcm_device);
2131 }
2132
2133 return 0;
2134}
2135
2136static int stop_input_stream(struct stream_in *in)
2137{
2138 struct audio_usecase *uc_info;
2139 struct audio_device *adev = in->dev;
2140
2141 adev->active_input = NULL;
2142 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2143 in->usecase, use_case_table[in->usecase]);
2144 uc_info = get_usecase_from_id(adev, in->usecase);
2145 if (uc_info == NULL) {
2146 ALOGE("%s: Could not find the usecase (%d) in the list",
2147 __func__, in->usecase);
2148 return -EINVAL;
2149 }
2150
2151 /* Disable the tx device */
2152 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2153
2154 list_remove(&uc_info->adev_list_node);
2155 free(uc_info);
2156
2157 if (list_empty(&in->pcm_dev_list)) {
2158 ALOGE("%s: pcm device list empty", __func__);
2159 return -EINVAL;
2160 }
2161
2162 in_release_pcm_devices(in);
2163 list_init(&in->pcm_dev_list);
2164
2165#ifdef HW_AEC_LOOPBACK
2166 if (in->hw_echo_reference)
2167 {
2168 in->hw_echo_reference = false;
2169 }
2170#endif
2171
2172 ALOGV("%s: exit", __func__);
2173 return 0;
2174}
2175
2176static int start_input_stream(struct stream_in *in)
2177{
2178 /* Enable output device and stream routing controls */
2179 int ret = 0;
2180 bool recreate_resampler = false;
2181 struct audio_usecase *uc_info;
2182 struct audio_device *adev = in->dev;
2183 struct pcm_device_profile *pcm_profile;
2184 struct pcm_device *pcm_device;
2185
2186 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2187 adev->active_input = in;
2188 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2189 if (pcm_profile == NULL) {
2190 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2191 __func__, in->usecase);
2192 ret = -EINVAL;
2193 goto error_config;
2194 }
2195
2196 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002197 if (uc_info == NULL) {
2198 ret = -ENOMEM;
2199 goto error_config;
2200 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002201 uc_info->id = in->usecase;
2202 uc_info->type = PCM_CAPTURE;
2203 uc_info->stream = (struct audio_stream *)in;
2204 uc_info->devices = in->devices;
2205 uc_info->in_snd_device = SND_DEVICE_NONE;
2206 uc_info->out_snd_device = SND_DEVICE_NONE;
2207
2208 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002209 if (pcm_device == NULL) {
2210 free(uc_info);
2211 ret = -ENOMEM;
2212 goto error_config;
2213 }
2214
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002215 pcm_device->pcm_profile = pcm_profile;
2216 list_init(&in->pcm_dev_list);
2217 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2218
2219 list_init(&uc_info->mixer_list);
2220 list_add_tail(&uc_info->mixer_list,
2221 &adev_get_mixer_for_card(adev,
2222 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2223
2224 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2225
2226 select_devices(adev, in->usecase);
2227
2228 /* Config should be updated as profile can be changed between different calls
2229 * to this function:
2230 * - Trigger resampler creation
2231 * - Config needs to be updated */
2232 if (in->config.rate != pcm_profile->config.rate) {
2233 recreate_resampler = true;
2234 }
2235 in->config = pcm_profile->config;
2236
2237#ifdef PREPROCESSING_ENABLED
2238 if (in->aux_channels_changed) {
2239 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2240 recreate_resampler = true;
2241 }
2242#endif
2243
2244 if (in->requested_rate != in->config.rate) {
2245 recreate_resampler = true;
2246 }
2247
2248 if (recreate_resampler) {
2249 if (in->resampler) {
2250 release_resampler(in->resampler);
2251 in->resampler = NULL;
2252 }
2253 in->buf_provider.get_next_buffer = get_next_buffer;
2254 in->buf_provider.release_buffer = release_buffer;
2255 ret = create_resampler(in->config.rate,
2256 in->requested_rate,
2257 in->config.channels,
2258 RESAMPLER_QUALITY_DEFAULT,
2259 &in->buf_provider,
2260 &in->resampler);
2261 }
2262
2263#ifdef PREPROCESSING_ENABLED
2264 if (in->enable_aec && in->echo_reference == NULL) {
2265 in->echo_reference = get_echo_reference(adev,
2266 AUDIO_FORMAT_PCM_16_BIT,
2267 audio_channel_count_from_in_mask(in->main_channels),
2268 in->requested_rate
2269 );
2270 }
2271
2272#ifdef HW_AEC_LOOPBACK
2273 if (in->enable_aec) {
2274 ret = get_hw_echo_reference(in);
2275 if (ret!=0)
2276 goto error_open;
2277
2278 /* force ref buffer reallocation */
2279 in->hw_ref_buf_size = 0;
2280 }
2281#endif
2282#endif
2283
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002284 if (in->dev->voice.in_call) {
2285 ALOGV("%s: in_call, not handling PCMs", __func__);
2286 goto skip_pcm_handling;
2287 }
2288
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002289 /* Open the PCM device.
2290 * The HW is limited to support only the default pcm_profile settings.
2291 * As such a change in aux_channels will not have an effect.
2292 */
2293 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2294 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2295 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2296 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2297
2298 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2299 if (!adev->sound_trigger_open_for_streaming) {
2300 ALOGE("%s: No handle to sound trigger HAL", __func__);
2301 ret = -EIO;
2302 goto error_open;
2303 }
2304 pcm_device->pcm = NULL;
2305 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2306 if (pcm_device->sound_trigger_handle <= 0) {
2307 ALOGE("%s: Failed to open DSP for streaming", __func__);
2308 ret = -EIO;
2309 goto error_open;
2310 }
2311 ALOGV("Opened DSP successfully");
2312 } else {
2313 pcm_device->sound_trigger_handle = 0;
2314 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2315 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2316
2317 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2318 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2319 pcm_close(pcm_device->pcm);
2320 pcm_device->pcm = NULL;
2321 ret = -EIO;
2322 goto error_open;
2323 }
2324 }
2325
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002326skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002327 /* force read and proc buffer reallocation in case of frame size or
2328 * channel count change */
2329 in->proc_buf_frames = 0;
2330 in->proc_buf_size = 0;
2331 in->read_buf_size = 0;
2332 in->read_buf_frames = 0;
2333
2334 /* if no supported sample rate is available, use the resampler */
2335 if (in->resampler) {
2336 in->resampler->reset(in->resampler);
2337 }
2338
2339 ALOGV("%s: exit", __func__);
2340 return ret;
2341
2342error_open:
2343 if (in->resampler) {
2344 release_resampler(in->resampler);
2345 in->resampler = NULL;
2346 }
2347 stop_input_stream(in);
2348
2349error_config:
2350 ALOGV("%s: exit: status(%d)", __func__, ret);
2351 adev->active_input = NULL;
2352 return ret;
2353}
2354
2355void lock_input_stream(struct stream_in *in)
2356{
2357 pthread_mutex_lock(&in->pre_lock);
2358 pthread_mutex_lock(&in->lock);
2359 pthread_mutex_unlock(&in->pre_lock);
2360}
2361
2362void lock_output_stream(struct stream_out *out)
2363{
2364 pthread_mutex_lock(&out->pre_lock);
2365 pthread_mutex_lock(&out->lock);
2366 pthread_mutex_unlock(&out->pre_lock);
2367}
2368
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002369static int uc_release_pcm_devices(struct audio_usecase *usecase)
2370{
2371 struct stream_out *out = (struct stream_out *)usecase->stream;
2372 struct pcm_device *pcm_device;
2373 struct listnode *node;
2374 struct listnode *next;
2375
2376 list_for_each_safe(node, next, &out->pcm_dev_list) {
2377 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2378 list_remove(node);
2379 free(pcm_device);
2380 }
2381 list_init(&usecase->mixer_list);
2382
2383 return 0;
2384}
2385
2386static int uc_select_pcm_devices(struct audio_usecase *usecase)
2387
2388{
2389 struct stream_out *out = (struct stream_out *)usecase->stream;
2390 struct pcm_device *pcm_device;
2391 struct pcm_device_profile *pcm_profile;
2392 struct mixer_card *mixer_card;
2393 audio_devices_t devices = usecase->devices;
2394
2395 list_init(&usecase->mixer_list);
2396 list_init(&out->pcm_dev_list);
2397
2398 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2399 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002400 if (pcm_device == NULL) {
2401 return -ENOMEM;
2402 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002403 pcm_device->pcm_profile = pcm_profile;
2404 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2405 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2406 if (mixer_card == NULL) {
2407 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2408 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2409 }
2410 devices &= ~pcm_profile->devices;
2411 }
2412
2413 return 0;
2414}
2415
2416static int out_close_pcm_devices(struct stream_out *out)
2417{
2418 struct pcm_device *pcm_device;
2419 struct listnode *node;
2420 struct audio_device *adev = out->dev;
2421
2422 list_for_each(node, &out->pcm_dev_list) {
2423 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2424 if (pcm_device->sound_trigger_handle > 0) {
2425 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2426 pcm_device->sound_trigger_handle = 0;
2427 }
2428 if (pcm_device->pcm) {
2429 pcm_close(pcm_device->pcm);
2430 pcm_device->pcm = NULL;
2431 }
2432 if (pcm_device->resampler) {
2433 release_resampler(pcm_device->resampler);
2434 pcm_device->resampler = NULL;
2435 }
2436 if (pcm_device->res_buffer) {
2437 free(pcm_device->res_buffer);
2438 pcm_device->res_buffer = NULL;
2439 }
2440 }
2441
2442 return 0;
2443}
2444
2445static int out_open_pcm_devices(struct stream_out *out)
2446{
2447 struct pcm_device *pcm_device;
2448 struct listnode *node;
2449 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002450 int pcm_device_card;
2451 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002452
2453 list_for_each(node, &out->pcm_dev_list) {
2454 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002455 pcm_device_card = pcm_device->pcm_profile->card;
2456 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002457
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002458 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2459 pcm_device_id = pcm_device_deep_buffer.id;
2460
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002461 if (out->dev->voice.in_call) {
2462 ALOGV("%s: in_call, not opening PCMs", __func__);
2463 return ret;
2464 }
2465
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002466 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2467 __func__, pcm_device_card, pcm_device_id);
2468
2469 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002470 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2471
2472 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2473 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2474 pcm_device->pcm = NULL;
2475 ret = -EIO;
2476 goto error_open;
2477 }
2478 /*
2479 * If the stream rate differs from the PCM rate, we need to
2480 * create a resampler.
2481 */
2482 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2483 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2484 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002485 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002486 out->sample_rate, pcm_device->pcm_profile->config.rate);
2487 ret = create_resampler(out->sample_rate,
2488 pcm_device->pcm_profile->config.rate,
2489 audio_channel_count_from_out_mask(out->channel_mask),
2490 RESAMPLER_QUALITY_DEFAULT,
2491 NULL,
2492 &pcm_device->resampler);
2493 pcm_device->res_byte_count = 0;
2494 pcm_device->res_buffer = NULL;
2495 }
2496 }
2497 return ret;
2498
2499error_open:
2500 out_close_pcm_devices(out);
2501 return ret;
2502}
2503
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002504int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002505{
2506 struct audio_device *adev = out->dev;
2507 struct audio_usecase *uc_info;
2508
2509 uc_info = get_usecase_from_id(adev, out->usecase);
2510 if (uc_info == NULL) {
2511 ALOGE("%s: Could not find the usecase (%d) in the list",
2512 __func__, out->usecase);
2513 return -EINVAL;
2514 }
2515 disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
2516 uc_release_pcm_devices(uc_info);
2517 list_remove(&uc_info->adev_list_node);
2518 free(uc_info);
2519
2520 return 0;
2521}
2522
Andreas Schneider56204f62017-01-31 08:17:32 +01002523int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002524{
2525 struct audio_device *adev = out->dev;
2526 struct audio_usecase *uc_info;
2527
2528 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002529 if (uc_info == NULL) {
2530 return -ENOMEM;
2531 }
2532
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002533 uc_info->id = out->usecase;
2534 uc_info->type = PCM_PLAYBACK;
2535 uc_info->stream = (struct audio_stream *)out;
2536 uc_info->devices = out->devices;
2537 uc_info->in_snd_device = SND_DEVICE_NONE;
2538 uc_info->out_snd_device = SND_DEVICE_NONE;
2539 uc_select_pcm_devices(uc_info);
2540
2541 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2542 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002543
2544 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002545}
2546
2547static int stop_output_stream(struct stream_out *out)
2548{
2549 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002550 bool do_disable = true;
2551
2552 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2553 out->usecase, use_case_table[out->usecase]);
2554
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002555 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002556
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002557 if (do_disable)
2558 ret = disable_output_path_l(out);
2559
2560 ALOGV("%s: exit: status(%d)", __func__, ret);
2561 return ret;
2562}
2563
2564static int start_output_stream(struct stream_out *out)
2565{
2566 int ret = 0;
2567 struct audio_device *adev = out->dev;
2568
2569 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2570 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2571
Andreas Schneider56204f62017-01-31 08:17:32 +01002572 ret = enable_output_path_l(out);
2573 if (ret != 0) {
2574 goto error_config;
2575 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002576
2577 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2578 out->compr = NULL;
2579 ret = out_open_pcm_devices(out);
2580 if (ret != 0)
2581 goto error_open;
2582#ifdef PREPROCESSING_ENABLED
2583 out->echo_reference = NULL;
2584 out->echo_reference_generation = adev->echo_reference_generation;
2585 if (adev->echo_reference != NULL)
2586 out->echo_reference = adev->echo_reference;
2587#endif
2588 } else {
2589 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2590 COMPRESS_IN, &out->compr_config);
2591 if (out->compr && !is_compress_ready(out->compr)) {
2592 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2593 compress_close(out->compr);
2594 out->compr = NULL;
2595 ret = -EIO;
2596 goto error_open;
2597 }
2598 if (out->offload_callback)
2599 compress_nonblock(out->compr, out->non_blocking);
2600
2601 if (adev->offload_fx_start_output != NULL)
2602 adev->offload_fx_start_output(out->handle);
2603 }
2604 ALOGV("%s: exit", __func__);
2605 return 0;
2606error_open:
2607 stop_output_stream(out);
2608error_config:
2609 return ret;
2610}
2611
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002612int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002613{
2614 struct audio_usecase *uc_info;
2615
2616 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002617 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002618
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002619 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002620
2621 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2622 if (uc_info == NULL) {
2623 ALOGE("%s: Could not find the usecase (%d) in the list",
2624 __func__, USECASE_VOICE_CALL);
2625 return -EINVAL;
2626 }
2627
2628 disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
2629 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2630
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002631 list_remove(&uc_info->adev_list_node);
2632 free(uc_info);
2633
2634 ALOGV("%s: exit", __func__);
2635 return 0;
2636}
2637
2638/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002639int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002640{
2641 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002642 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002643
2644 ALOGV("%s: enter", __func__);
2645
2646 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002647 if (uc_info == NULL) {
2648 ret = -ENOMEM;
2649 goto exit;
2650 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002651 /*
2652 * We set this early so that functions called after this is being set
2653 * can use it. It is e.g. needed in select_devices() to inform the RILD
2654 * which output device we use.
2655 */
2656 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002657
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002658 uc_info->id = USECASE_VOICE_CALL;
2659 uc_info->type = VOICE_CALL;
2660 uc_info->stream = (struct audio_stream *)adev->primary_output;
2661 uc_info->devices = adev->primary_output->devices;
2662 uc_info->in_snd_device = SND_DEVICE_NONE;
2663 uc_info->out_snd_device = SND_DEVICE_NONE;
2664
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002665 list_init(&uc_info->mixer_list);
2666 list_add_tail(&uc_info->mixer_list,
2667 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002668
2669 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2670
2671 select_devices(adev, USECASE_VOICE_CALL);
2672
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002673 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002674
2675 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002676 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002677
Andreas Schneider56204f62017-01-31 08:17:32 +01002678exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002679 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002680 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002681}
2682
2683static int check_input_parameters(uint32_t sample_rate,
2684 audio_format_t format,
2685 int channel_count)
2686{
2687 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2688
2689 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2690
2691 switch (sample_rate) {
2692 case 8000:
2693 case 11025:
2694 case 12000:
2695 case 16000:
2696 case 22050:
2697 case 24000:
2698 case 32000:
2699 case 44100:
2700 case 48000:
2701 break;
2702 default:
2703 return -EINVAL;
2704 }
2705
2706 return 0;
2707}
2708
2709static size_t get_input_buffer_size(uint32_t sample_rate,
2710 audio_format_t format,
2711 int channel_count,
2712 usecase_type_t usecase_type,
2713 audio_devices_t devices)
2714{
2715 size_t size = 0;
2716 struct pcm_device_profile *pcm_profile;
2717
2718 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2719 return 0;
2720
2721 pcm_profile = get_pcm_device(usecase_type, devices);
2722 if (pcm_profile == NULL)
2723 return 0;
2724
2725 /*
2726 * take resampling into account and return the closest majoring
2727 * multiple of 16 frames, as audioflinger expects audio buffers to
2728 * be a multiple of 16 frames
2729 */
2730 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2731 size = ((size + 15) / 16) * 16;
2732
2733 return (size * channel_count * audio_bytes_per_sample(format));
2734
2735}
2736
2737static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2738{
2739 struct stream_out *out = (struct stream_out *)stream;
2740
2741 return out->sample_rate;
2742}
2743
2744static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2745{
2746 (void)stream;
2747 (void)rate;
2748 return -ENOSYS;
2749}
2750
2751static size_t out_get_buffer_size(const struct audio_stream *stream)
2752{
2753 struct stream_out *out = (struct stream_out *)stream;
2754
2755 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2756 return out->compr_config.fragment_size;
2757 }
2758
2759 return out->config.period_size *
2760 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2761}
2762
2763static uint32_t out_get_channels(const struct audio_stream *stream)
2764{
2765 struct stream_out *out = (struct stream_out *)stream;
2766
2767 return out->channel_mask;
2768}
2769
2770static audio_format_t out_get_format(const struct audio_stream *stream)
2771{
2772 struct stream_out *out = (struct stream_out *)stream;
2773
2774 return out->format;
2775}
2776
2777static int out_set_format(struct audio_stream *stream, audio_format_t format)
2778{
2779 (void)stream;
2780 (void)format;
2781 return -ENOSYS;
2782}
2783
2784static int do_out_standby_l(struct stream_out *out)
2785{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002786 int status = 0;
2787
2788 out->standby = true;
2789 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2790 out_close_pcm_devices(out);
2791#ifdef PREPROCESSING_ENABLED
2792 /* stop writing to echo reference */
2793 if (out->echo_reference != NULL) {
2794 out->echo_reference->write(out->echo_reference, NULL);
2795 if (out->echo_reference_generation != adev->echo_reference_generation) {
2796 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2797 release_echo_reference(out->echo_reference);
2798 out->echo_reference_generation = adev->echo_reference_generation;
2799 }
2800 out->echo_reference = NULL;
2801 }
2802#endif
2803 } else {
2804 stop_compressed_output_l(out);
2805 out->gapless_mdata.encoder_delay = 0;
2806 out->gapless_mdata.encoder_padding = 0;
2807 if (out->compr != NULL) {
2808 compress_close(out->compr);
2809 out->compr = NULL;
2810 }
2811 }
2812 status = stop_output_stream(out);
2813
2814 return status;
2815}
2816
2817static int out_standby(struct audio_stream *stream)
2818{
2819 struct stream_out *out = (struct stream_out *)stream;
2820 struct audio_device *adev = out->dev;
2821
2822 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2823 out->usecase, use_case_table[out->usecase]);
2824 lock_output_stream(out);
2825 if (!out->standby) {
2826 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002827 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002828 do_out_standby_l(out);
2829 pthread_mutex_unlock(&adev->lock);
2830 }
2831 pthread_mutex_unlock(&out->lock);
2832 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002833
2834 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2835
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002836 return 0;
2837}
2838
2839static int out_dump(const struct audio_stream *stream, int fd)
2840{
2841 (void)stream;
2842 (void)fd;
2843
2844 return 0;
2845}
2846
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002847static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2848{
2849 struct stream_out *out = (struct stream_out *)stream;
2850 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002851 struct listnode *node;
2852 struct str_parms *parms;
2853 char value[32];
2854 int ret, val = 0;
2855 struct audio_usecase *uc_info;
2856 bool do_standby = false;
2857 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002858#ifdef PREPROCESSING_ENABLED
2859 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2860#endif
2861
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002862 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2863 "adev->mode(%#x)",
2864 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2865 out->devices, adev->mode);
2866
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002867 parms = str_parms_create_str(kvpairs);
2868 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2869 if (ret >= 0) {
2870 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002871
2872 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2873 __func__, out->usecase, use_case_table[out->usecase], val,
2874 adev->mode);
2875
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002876 pthread_mutex_lock(&adev->lock_inputs);
2877 lock_output_stream(out);
2878 pthread_mutex_lock(&adev->lock);
2879#ifdef PREPROCESSING_ENABLED
2880 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2881 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2882 /* reset active input:
2883 * - to attach the echo reference
2884 * - because a change in output device may change mic settings */
2885 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2886 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2887 in = adev->active_input;
2888 }
2889 }
2890#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002891 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002892 bool bt_sco_active = false;
2893
2894 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2895 bt_sco_active = true;
2896 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002897 out->devices = val;
2898
2899 if (!out->standby) {
2900 uc_info = get_usecase_from_id(adev, out->usecase);
2901 if (uc_info == NULL) {
2902 ALOGE("%s: Could not find the usecase (%d) in the list",
2903 __func__, out->usecase);
2904 } else {
2905 list_for_each(node, &out->pcm_dev_list) {
2906 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2907 if ((pcm_device->pcm_profile->devices & val) == 0)
2908 do_standby = true;
2909 val &= ~pcm_device->pcm_profile->devices;
2910 }
2911 if (val != 0)
2912 do_standby = true;
2913 }
2914 if (do_standby)
2915 do_out_standby_l(out);
2916 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002917 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2918 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002919 select_devices(adev, out->usecase);
2920 }
2921 }
2922
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002923 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002924 (out == adev->primary_output)) {
2925 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002926 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2927 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002928 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002929 /* Turn on bluetooth if needed */
2930 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002931 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002932 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002933 } else {
2934 /*
2935 * When we select different devices we need to restart the
2936 * voice call. The modem closes the stream on its end and
2937 * we do not get any output.
2938 */
2939 stop_voice_call(adev);
2940 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002941 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002942 }
2943 }
2944
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002945 if ((adev->mode == AUDIO_MODE_NORMAL) && adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002946 (out == adev->primary_output)) {
2947 stop_voice_call(adev);
2948 }
2949 pthread_mutex_unlock(&adev->lock);
2950 pthread_mutex_unlock(&out->lock);
2951#ifdef PREPROCESSING_ENABLED
2952 if (in) {
2953 /* The lock on adev->lock_inputs prevents input stream from being closed */
2954 lock_input_stream(in);
2955 pthread_mutex_lock(&adev->lock);
2956 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2957 do_in_standby_l(in);
2958 pthread_mutex_unlock(&adev->lock);
2959 pthread_mutex_unlock(&in->lock);
2960 }
2961#endif
2962 pthread_mutex_unlock(&adev->lock_inputs);
2963 }
2964
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002965 amplifier_set_parameters(parms);
2966
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002967 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2968 parse_compress_metadata(out, parms);
2969 }
2970
2971 str_parms_destroy(parms);
2972
2973 if (ret > 0)
2974 ret = 0;
2975 ALOGV("%s: exit: code(%d)", __func__, ret);
2976 return ret;
2977}
2978
2979static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2980{
2981 struct stream_out *out = (struct stream_out *)stream;
2982 struct str_parms *query = str_parms_create_str(keys);
2983 char *str;
2984 char value[256];
2985 struct str_parms *reply = str_parms_create();
2986 size_t i, j;
2987 int ret;
2988 bool first = true;
2989 ALOGV("%s: enter: keys - %s", __func__, keys);
2990 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2991 if (ret >= 0) {
2992 value[0] = '\0';
2993 i = 0;
2994 while (out->supported_channel_masks[i] != 0) {
2995 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2996 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2997 if (!first) {
2998 strcat(value, "|");
2999 }
3000 strcat(value, out_channels_name_to_enum_table[j].name);
3001 first = false;
3002 break;
3003 }
3004 }
3005 i++;
3006 }
3007 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
3008 str = str_parms_to_str(reply);
3009 } else {
3010 str = strdup(keys);
3011 }
3012 str_parms_destroy(query);
3013 str_parms_destroy(reply);
3014 ALOGV("%s: exit: returns - %s", __func__, str);
3015 return str;
3016}
3017
3018static uint32_t out_get_latency(const struct audio_stream_out *stream)
3019{
3020 struct stream_out *out = (struct stream_out *)stream;
3021
3022 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3023 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
3024
3025 return (out->config.period_count * out->config.period_size * 1000) /
3026 (out->config.rate);
3027}
3028
3029static int out_set_volume(struct audio_stream_out *stream, float left,
3030 float right)
3031{
3032 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003033
3034 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
3035 /* only take left channel into account: the API is for stereo anyway */
3036 out->muted = (left == 0.0f);
3037 return 0;
3038 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003039 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003040 }
3041
3042 return -ENOSYS;
3043}
3044
Andreas Schneider3b643832017-01-31 11:48:22 +01003045#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003046static int fast_set_affinity(pid_t tid) {
3047 cpu_set_t cpu_set;
3048 int cpu_num;
3049 const char *irq_procfs = "/proc/asound/irq_affinity";
3050 FILE *fp;
3051
3052 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3053 ALOGW("Procfs node %s not found", irq_procfs);
3054 return -1;
3055 }
3056
3057 if (fscanf(fp, "%d", &cpu_num) != 1) {
3058 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3059 fclose(fp);
3060 return -1;
3061 }
3062 fclose(fp);
3063
3064 CPU_ZERO(&cpu_set);
3065 CPU_SET(cpu_num, &cpu_set);
3066 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3067}
Andreas Schneider3b643832017-01-31 11:48:22 +01003068#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003069
3070static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3071 size_t bytes)
3072{
3073 struct stream_out *out = (struct stream_out *)stream;
3074 struct audio_device *adev = out->dev;
3075 ssize_t ret = 0;
3076 struct pcm_device *pcm_device;
3077 struct listnode *node;
3078 size_t frame_size = audio_stream_out_frame_size(stream);
3079 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003080#ifdef PREPROCESSING_ENABLED
3081 size_t in_frames = bytes / frame_size;
3082 size_t out_frames = in_frames;
3083 struct stream_in *in = NULL;
3084#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003085
3086 lock_output_stream(out);
3087
Andreas Schneider3b643832017-01-31 11:48:22 +01003088#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003089 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003090 pid_t tid = gettid();
3091 int err;
3092
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003093 err = fast_set_affinity(tid);
3094 if (err < 0) {
3095 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3096 }
3097 out->is_fastmixer_affinity_set = true;
3098 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003099#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003100
3101 if (out->standby) {
3102#ifdef PREPROCESSING_ENABLED
3103 pthread_mutex_unlock(&out->lock);
3104 /* Prevent input stream from being closed */
3105 pthread_mutex_lock(&adev->lock_inputs);
3106 lock_output_stream(out);
3107 if (!out->standby) {
3108 pthread_mutex_unlock(&adev->lock_inputs);
3109 goto false_alarm;
3110 }
3111#endif
3112 pthread_mutex_lock(&adev->lock);
3113 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003114 if (ret == 0) {
3115 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3116 }
3117
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003118 /* ToDo: If use case is compress offload should return 0 */
3119 if (ret != 0) {
3120 pthread_mutex_unlock(&adev->lock);
3121#ifdef PREPROCESSING_ENABLED
3122 pthread_mutex_unlock(&adev->lock_inputs);
3123#endif
3124 goto exit;
3125 }
3126 out->standby = false;
3127
3128#ifdef PREPROCESSING_ENABLED
3129 /* A change in output device may change the microphone selection */
3130 if (adev->active_input &&
3131 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3132 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3133 in = adev->active_input;
3134 ALOGV("%s: enter:) force_input_standby true", __func__);
3135 }
3136#endif
3137 pthread_mutex_unlock(&adev->lock);
3138#ifdef PREPROCESSING_ENABLED
3139 if (!in) {
3140 /* Leave mutex locked iff in != NULL */
3141 pthread_mutex_unlock(&adev->lock_inputs);
3142 }
3143#endif
3144 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003145#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003146false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003147#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003148
3149 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003150 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003151 return ret;
3152 } else {
3153#ifdef PREPROCESSING_ENABLED
3154 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3155 != out->echo_reference_generation) {
3156 pthread_mutex_lock(&adev->lock);
3157 if (out->echo_reference != NULL) {
3158 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3159 release_echo_reference(out->echo_reference);
3160 }
3161 // note that adev->echo_reference_generation here can be different from the one
3162 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3163 // with what has been set by get_echo_reference() or put_echo_reference()
3164 out->echo_reference_generation = adev->echo_reference_generation;
3165 out->echo_reference = adev->echo_reference;
3166 ALOGV("%s: update echo reference generation %d", __func__,
3167 out->echo_reference_generation);
3168 pthread_mutex_unlock(&adev->lock);
3169 }
3170#endif
3171
3172 if (out->muted)
3173 memset((void *)buffer, 0, bytes);
3174 list_for_each(node, &out->pcm_dev_list) {
3175 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3176 if (pcm_device->resampler) {
3177 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3178 > pcm_device->res_byte_count) {
3179 pcm_device->res_byte_count =
3180 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3181 pcm_device->res_buffer =
3182 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3183 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3184 pcm_device->res_byte_count);
3185 }
3186 frames_rq = bytes / frame_size;
3187 frames_wr = pcm_device->res_byte_count / frame_size;
3188 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3189 __func__, frames_rq, frame_size);
3190 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3191 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3192 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3193 }
3194 if (pcm_device->pcm) {
3195#ifdef PREPROCESSING_ENABLED
3196 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3197 struct echo_reference_buffer b;
3198 b.raw = (void *)buffer;
3199 b.frame_count = in_frames;
3200
3201 get_playback_delay(out, out_frames, &b);
3202 out->echo_reference->write(out->echo_reference, &b);
3203 }
3204#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003205 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3206 if (pcm_device->resampler && pcm_device->res_buffer)
3207 pcm_device->status =
3208 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3209 frames_wr * frame_size);
3210 else
3211 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3212 if (pcm_device->status != 0)
3213 ret = pcm_device->status;
3214 }
3215 }
3216 if (ret == 0)
3217 out->written += bytes / (out->config.channels * sizeof(short));
3218 }
3219
3220exit:
3221 pthread_mutex_unlock(&out->lock);
3222
3223 if (ret != 0) {
3224 list_for_each(node, &out->pcm_dev_list) {
3225 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3226 if (pcm_device->pcm && pcm_device->status != 0)
3227 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3228 }
3229 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003230 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3231 clock_gettime(CLOCK_MONOTONIC, &t);
3232 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3233 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3234 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3235 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3236 if (sleep_time > 0) {
3237 usleep(sleep_time);
3238 } else {
3239 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3240 sleep_time = 0;
3241 }
3242 out->last_write_time_us = now + sleep_time;
3243 // last_write_time_us is an approximation of when the (simulated) alsa
3244 // buffer is believed completely full. The usleep above waits for more space
3245 // in the buffer, but by the end of the sleep the buffer is considered
3246 // topped-off.
3247 //
3248 // On the subsequent out_write(), we measure the elapsed time spent in
3249 // the mixer. This is subtracted from the sleep estimate based on frames,
3250 // thereby accounting for drain in the alsa buffer during mixing.
3251 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003252 }
3253
3254#ifdef PREPROCESSING_ENABLED
3255 if (in) {
3256 /* The lock on adev->lock_inputs prevents input stream from being closed */
3257 lock_input_stream(in);
3258 pthread_mutex_lock(&adev->lock);
3259 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3260 do_in_standby_l(in);
3261 pthread_mutex_unlock(&adev->lock);
3262 pthread_mutex_unlock(&in->lock);
3263 /* This mutex was left locked iff in != NULL */
3264 pthread_mutex_unlock(&adev->lock_inputs);
3265 }
3266#endif
3267
3268 return bytes;
3269}
3270
3271static int out_get_render_position(const struct audio_stream_out *stream,
3272 uint32_t *dsp_frames)
3273{
3274 struct stream_out *out = (struct stream_out *)stream;
3275 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003276 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3277 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003278 } else
3279 return -EINVAL;
3280}
3281
3282static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3283{
3284 (void)stream;
3285 (void)effect;
3286 return 0;
3287}
3288
3289static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3290{
3291 (void)stream;
3292 (void)effect;
3293 return 0;
3294}
3295
3296static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3297 int64_t *timestamp)
3298{
3299 (void)stream;
3300 (void)timestamp;
3301 return -EINVAL;
3302}
3303
3304static int out_get_presentation_position(const struct audio_stream_out *stream,
3305 uint64_t *frames, struct timespec *timestamp)
3306{
3307 struct stream_out *out = (struct stream_out *)stream;
3308 int ret = -1;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003309
3310 lock_output_stream(out);
3311
3312 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003313 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003314 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003315 if (out->dev->voice.in_call) {
3316 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3317 ret = 0;
3318 goto done;
3319 }
3320
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003321 /* FIXME: which device to read from? */
3322 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003323 struct pcm_device *pcm_device;
3324 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003325 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003326
Andreas Schneiderd6359182017-02-08 16:58:22 +01003327 list_for_each(node, &out->pcm_dev_list) {
3328 pcm_device = node_to_item(node,
3329 struct pcm_device,
3330 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003331
Andreas Schneiderd6359182017-02-08 16:58:22 +01003332 if (pcm_device->pcm != NULL) {
3333 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3334 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3335 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3336 /* This adjustment accounts for buffering after app processor.
3337 It is based on estimated DSP latency per use case, rather than exact. */
3338 signed_frames -=
3339 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3340
3341 /* It would be unusual for this value to be negative, but check just in case ... */
3342 if (signed_frames >= 0) {
3343 *frames = signed_frames;
3344 ret = 0;
3345 goto done;
3346 }
3347 ret = -1;
3348 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003349 }
3350 }
3351 }
3352 }
3353
Andreas Schneiderd6359182017-02-08 16:58:22 +01003354done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003355 pthread_mutex_unlock(&out->lock);
3356
3357 return ret;
3358}
3359
3360static int out_set_callback(struct audio_stream_out *stream,
3361 stream_callback_t callback, void *cookie)
3362{
3363 struct stream_out *out = (struct stream_out *)stream;
3364
3365 ALOGV("%s", __func__);
3366 lock_output_stream(out);
3367 out->offload_callback = callback;
3368 out->offload_cookie = cookie;
3369 pthread_mutex_unlock(&out->lock);
3370 return 0;
3371}
3372
3373static int out_pause(struct audio_stream_out* stream)
3374{
3375 struct stream_out *out = (struct stream_out *)stream;
3376 int status = -ENOSYS;
3377 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003378 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3379 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003380 return status;
3381}
3382
3383static int out_resume(struct audio_stream_out* stream)
3384{
3385 struct stream_out *out = (struct stream_out *)stream;
3386 int status = -ENOSYS;
3387 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003388 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3389 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003390 return status;
3391}
3392
3393static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3394{
3395 struct stream_out *out = (struct stream_out *)stream;
3396 int status = -ENOSYS;
3397 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003398 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3399 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003400 return status;
3401}
3402
3403static int out_flush(struct audio_stream_out* stream)
3404{
3405 struct stream_out *out = (struct stream_out *)stream;
3406 ALOGV("%s", __func__);
3407 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003408 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003409 }
3410 return -ENOSYS;
3411}
3412
3413/** audio_stream_in implementation **/
3414static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3415{
3416 struct stream_in *in = (struct stream_in *)stream;
3417
3418 return in->requested_rate;
3419}
3420
3421static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3422{
3423 (void)stream;
3424 (void)rate;
3425 return -ENOSYS;
3426}
3427
3428static uint32_t in_get_channels(const struct audio_stream *stream)
3429{
3430 struct stream_in *in = (struct stream_in *)stream;
3431
3432 return in->main_channels;
3433}
3434
3435static audio_format_t in_get_format(const struct audio_stream *stream)
3436{
3437 (void)stream;
3438 return AUDIO_FORMAT_PCM_16_BIT;
3439}
3440
3441static int in_set_format(struct audio_stream *stream, audio_format_t format)
3442{
3443 (void)stream;
3444 (void)format;
3445
3446 return -ENOSYS;
3447}
3448
3449static size_t in_get_buffer_size(const struct audio_stream *stream)
3450{
3451 struct stream_in *in = (struct stream_in *)stream;
3452
3453 return get_input_buffer_size(in->requested_rate,
3454 in_get_format(stream),
3455 audio_channel_count_from_in_mask(in->main_channels),
3456 in->usecase_type,
3457 in->devices);
3458}
3459
3460static int in_close_pcm_devices(struct stream_in *in)
3461{
3462 struct pcm_device *pcm_device;
3463 struct listnode *node;
3464 struct audio_device *adev = in->dev;
3465
3466 list_for_each(node, &in->pcm_dev_list) {
3467 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3468 if (pcm_device) {
3469 if (pcm_device->pcm)
3470 pcm_close(pcm_device->pcm);
3471 pcm_device->pcm = NULL;
3472 if (pcm_device->sound_trigger_handle > 0)
3473 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3474 pcm_device->sound_trigger_handle = 0;
3475 }
3476 }
3477 return 0;
3478}
3479
3480
3481/* must be called with stream and hw device mutex locked */
3482static int do_in_standby_l(struct stream_in *in)
3483{
3484 int status = 0;
3485
3486#ifdef PREPROCESSING_ENABLED
3487 struct audio_device *adev = in->dev;
3488#endif
3489 if (!in->standby) {
3490
3491 in_close_pcm_devices(in);
3492
3493#ifdef PREPROCESSING_ENABLED
3494 if (in->echo_reference != NULL) {
3495 /* stop reading from echo reference */
3496 in->echo_reference->read(in->echo_reference, NULL);
3497 put_echo_reference(adev, in->echo_reference);
3498 in->echo_reference = NULL;
3499 }
3500#ifdef HW_AEC_LOOPBACK
3501 if (in->hw_echo_reference)
3502 {
3503 if (in->hw_ref_buf) {
3504 free(in->hw_ref_buf);
3505 in->hw_ref_buf = NULL;
3506 }
3507 }
3508#endif // HW_AEC_LOOPBACK
3509#endif // PREPROCESSING_ENABLED
3510
3511 status = stop_input_stream(in);
3512
3513 if (in->read_buf) {
3514 free(in->read_buf);
3515 in->read_buf = NULL;
3516 }
3517
3518 in->standby = 1;
3519 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003520
3521 in->last_read_time_us = 0;
3522
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003523 return 0;
3524}
3525
3526// called with adev->lock_inputs locked
3527static int in_standby_l(struct stream_in *in)
3528{
3529 struct audio_device *adev = in->dev;
3530 int status = 0;
3531 lock_input_stream(in);
3532 if (!in->standby) {
3533 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003534 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003535 status = do_in_standby_l(in);
3536 pthread_mutex_unlock(&adev->lock);
3537 }
3538 pthread_mutex_unlock(&in->lock);
3539 return status;
3540}
3541
3542static int in_standby(struct audio_stream *stream)
3543{
3544 struct stream_in *in = (struct stream_in *)stream;
3545 struct audio_device *adev = in->dev;
3546 int status;
3547 ALOGV("%s: enter", __func__);
3548 pthread_mutex_lock(&adev->lock_inputs);
3549 status = in_standby_l(in);
3550 pthread_mutex_unlock(&adev->lock_inputs);
3551 ALOGV("%s: exit: status(%d)", __func__, status);
3552 return status;
3553}
3554
3555static int in_dump(const struct audio_stream *stream, int fd)
3556{
3557 (void)stream;
3558 (void)fd;
3559
3560 return 0;
3561}
3562
3563static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3564{
3565 struct stream_in *in = (struct stream_in *)stream;
3566 struct audio_device *adev = in->dev;
3567 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003568 char value[32];
3569 int ret, val = 0;
3570 struct audio_usecase *uc_info;
3571 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003572 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003573
3574 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3575 parms = str_parms_create_str(kvpairs);
3576
3577 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3578
3579 pthread_mutex_lock(&adev->lock_inputs);
3580 lock_input_stream(in);
3581 pthread_mutex_lock(&adev->lock);
3582 if (ret >= 0) {
3583 val = atoi(value);
3584 /* no audio source uses val == 0 */
3585 if (((int)in->source != val) && (val != 0)) {
3586 in->source = val;
3587 }
3588 }
3589
3590 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3591 if (ret >= 0) {
3592 val = atoi(value);
3593 if (((int)in->devices != val) && (val != 0)) {
3594 in->devices = val;
3595 /* If recording is in progress, change the tx device to new device */
3596 if (!in->standby) {
3597 uc_info = get_usecase_from_id(adev, in->usecase);
3598 if (uc_info == NULL) {
3599 ALOGE("%s: Could not find the usecase (%d) in the list",
3600 __func__, in->usecase);
3601 } else {
3602 if (list_empty(&in->pcm_dev_list))
3603 ALOGE("%s: pcm device list empty", __func__);
3604 else {
3605 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3606 struct pcm_device, stream_list_node);
3607 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3608 do_standby = true;
3609 }
3610 }
3611 }
3612 if (do_standby) {
3613 ret = do_in_standby_l(in);
3614 } else
3615 ret = select_devices(adev, in->usecase);
3616 }
3617 }
3618 }
3619 pthread_mutex_unlock(&adev->lock);
3620 pthread_mutex_unlock(&in->lock);
3621 pthread_mutex_unlock(&adev->lock_inputs);
3622 str_parms_destroy(parms);
3623
3624 if (ret > 0)
3625 ret = 0;
3626
3627 ALOGV("%s: exit: status(%d)", __func__, ret);
3628 return ret;
3629}
3630
3631static char* in_get_parameters(const struct audio_stream *stream,
3632 const char *keys)
3633{
3634 (void)stream;
3635 (void)keys;
3636
3637 return strdup("");
3638}
3639
3640static int in_set_gain(struct audio_stream_in *stream, float gain)
3641{
3642 (void)stream;
3643 (void)gain;
3644
3645 return 0;
3646}
3647
3648static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3649 size_t bytes)
3650{
3651 struct pcm_device *pcm_device;
3652 struct audio_device *adev = in->dev;
3653
3654 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3655 struct pcm_device, stream_list_node);
3656
3657 if (pcm_device->sound_trigger_handle > 0)
3658 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3659 else
3660 return 0;
3661}
3662
3663static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3664 size_t bytes)
3665{
3666 struct stream_in *in = (struct stream_in *)stream;
3667 struct audio_device *adev = in->dev;
3668 ssize_t frames = -1;
3669 int ret = -1;
3670 int read_and_process_successful = false;
3671
3672 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003673
3674 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3675 lock_input_stream(in);
3676
Andreas Schneider3b643832017-01-31 11:48:22 +01003677#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003678 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003679 pid_t tid = gettid();
3680 int err;
3681
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003682 err = fast_set_affinity(tid);
3683 if (err < 0) {
3684 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3685 }
3686 in->is_fastcapture_affinity_set = true;
3687 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003688#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003689
3690 if (in->standby) {
3691 pthread_mutex_unlock(&in->lock);
3692 pthread_mutex_lock(&adev->lock_inputs);
3693 lock_input_stream(in);
3694 if (!in->standby) {
3695 pthread_mutex_unlock(&adev->lock_inputs);
3696 goto false_alarm;
3697 }
3698 pthread_mutex_lock(&adev->lock);
3699 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003700 if (ret == 0) {
3701 amplifier_input_stream_start(stream);
3702 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003703 pthread_mutex_unlock(&adev->lock);
3704 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003705
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003706 if (ret != 0) {
3707 goto exit;
3708 }
3709 in->standby = 0;
3710 }
3711false_alarm:
3712
3713 if (!list_empty(&in->pcm_dev_list)) {
3714 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3715 bytes = read_bytes_from_dsp(in, buffer, bytes);
3716 if (bytes > 0)
3717 read_and_process_successful = true;
3718 } else {
3719 /*
3720 * Read PCM and:
3721 * - resample if needed
3722 * - process if pre-processors are attached
3723 * - discard unwanted channels
3724 */
3725 frames = read_and_process_frames(in, buffer, frames_rq);
3726 if (frames >= 0)
3727 read_and_process_successful = true;
3728 }
3729 }
3730
3731 /*
3732 * Instead of writing zeroes here, we could trust the hardware
3733 * to always provide zeroes when muted.
3734 */
3735 if (read_and_process_successful == true && adev->mic_mute)
3736 memset(buffer, 0, bytes);
3737
3738exit:
3739 pthread_mutex_unlock(&in->lock);
3740
3741 if (read_and_process_successful == false) {
3742 in_standby(&in->stream.common);
3743 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003744 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3745 clock_gettime(CLOCK_MONOTONIC, &t);
3746 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3747
3748 // we do a full sleep when exiting standby.
3749 const bool standby = in->last_read_time_us == 0;
3750 const int64_t elapsed_time_since_last_read = standby ?
3751 0 : now - in->last_read_time_us;
3752 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3753 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3754 if (sleep_time > 0) {
3755 usleep(sleep_time);
3756 } else {
3757 sleep_time = 0;
3758 }
3759 in->last_read_time_us = now + sleep_time;
3760 // last_read_time_us is an approximation of when the (simulated) alsa
3761 // buffer is drained by the read, and is empty.
3762 //
3763 // On the subsequent in_read(), we measure the elapsed time spent in
3764 // the recording thread. This is subtracted from the sleep estimate based on frames,
3765 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003766 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003767 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003768
3769 if (bytes > 0) {
3770 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3771 }
3772
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003773 return bytes;
3774}
3775
3776static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3777{
3778 (void)stream;
3779
3780 return 0;
3781}
3782
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003783static int in_get_capture_position(const struct audio_stream_in *stream,
3784 int64_t *frames, int64_t *time)
3785{
3786 if (stream == NULL || frames == NULL || time == NULL) {
3787 return -EINVAL;
3788 }
3789
3790 struct stream_in *in = (struct stream_in *)stream;
3791 struct pcm_device *pcm_device;
3792 int ret = -ENOSYS;
3793
3794 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3795 struct pcm_device, stream_list_node);
3796
3797 pthread_mutex_lock(&in->lock);
3798 if (pcm_device->pcm) {
3799 struct timespec timestamp;
3800 unsigned int avail;
3801 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3802 *frames = in->frames_read + avail;
3803 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3804 ret = 0;
3805 }
3806 }
3807
3808 pthread_mutex_unlock(&in->lock);
3809 return ret;
3810}
3811
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003812static int add_remove_audio_effect(const struct audio_stream *stream,
3813 effect_handle_t effect,
3814 bool enable)
3815{
3816 struct stream_in *in = (struct stream_in *)stream;
3817 struct audio_device *adev = in->dev;
3818 int status = 0;
3819 effect_descriptor_t desc;
3820#ifdef PREPROCESSING_ENABLED
3821 int i;
3822#endif
3823 status = (*effect)->get_descriptor(effect, &desc);
3824 if (status != 0)
3825 return status;
3826
3827 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3828
3829 pthread_mutex_lock(&adev->lock_inputs);
3830 lock_input_stream(in);
3831 pthread_mutex_lock(&in->dev->lock);
3832#ifndef PREPROCESSING_ENABLED
3833 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3834 in->enable_aec != enable &&
3835 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3836 in->enable_aec = enable;
3837 if (!in->standby)
3838 select_devices(in->dev, in->usecase);
3839 }
3840#else
3841 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3842 status = -ENOSYS;
3843 goto exit;
3844 }
3845 if ( enable == true ) {
3846 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3847 /* add the supported channel of the effect in the channel_configs */
3848 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3849 in->num_preprocessors ++;
3850 /* check compatibility between main channel supported and possible auxiliary channels */
3851 in_update_aux_channels(in, effect);//wesley crash
3852 in->aux_channels_changed = true;
3853 } else {
3854 /* if ( enable == false ) */
3855 if (in->num_preprocessors <= 0) {
3856 status = -ENOSYS;
3857 goto exit;
3858 }
3859 status = -EINVAL;
3860 for (i=0; i < in->num_preprocessors; i++) {
3861 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3862 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3863 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3864 in->preprocessors[i - 1].num_channel_configs =
3865 in->preprocessors[i].num_channel_configs;
3866 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3867 continue;
3868 }
3869 if ( in->preprocessors[i].effect_itfe == effect ) {
3870 ALOGV("add_remove_audio_effect found fx at index %d", i);
3871 free(in->preprocessors[i].channel_configs);
3872 status = 0;
3873 }
3874 }
3875 if (status != 0)
3876 goto exit;
3877 in->num_preprocessors--;
3878 /* if we remove one effect, at least the last proproc should be reset */
3879 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3880 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3881 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3882 in->aux_channels_changed = false;
3883 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3884 }
3885 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3886
3887 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3888 in->enable_aec = enable;
3889 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3890 if (!in->standby) {
3891 select_devices(in->dev, in->usecase);
3892 do_in_standby_l(in);
3893 }
3894 if (in->enable_aec == true) {
3895 in_configure_reverse(in);
3896 }
3897 }
3898exit:
3899#endif
3900 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3901 pthread_mutex_unlock(&in->dev->lock);
3902 pthread_mutex_unlock(&in->lock);
3903 pthread_mutex_unlock(&adev->lock_inputs);
3904 return status;
3905}
3906
3907static int in_add_audio_effect(const struct audio_stream *stream,
3908 effect_handle_t effect)
3909{
3910 ALOGV("%s: effect %p", __func__, effect);
3911 return add_remove_audio_effect(stream, effect, true);
3912}
3913
3914static int in_remove_audio_effect(const struct audio_stream *stream,
3915 effect_handle_t effect)
3916{
3917 ALOGV("%s: effect %p", __func__, effect);
3918 return add_remove_audio_effect(stream, effect, false);
3919}
3920
3921static int adev_open_output_stream(struct audio_hw_device *dev,
3922 audio_io_handle_t handle,
3923 audio_devices_t devices,
3924 audio_output_flags_t flags,
3925 struct audio_config *config,
3926 struct audio_stream_out **stream_out,
3927 const char *address __unused)
3928{
3929 struct audio_device *adev = (struct audio_device *)dev;
3930 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003931 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003932 struct pcm_device_profile *pcm_profile;
3933
3934 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3935 __func__, config->sample_rate, config->channel_mask, devices, flags);
3936 *stream_out = NULL;
3937 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003938 if (out == NULL) {
3939 ret = -ENOMEM;
3940 goto error_config;
3941 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003942
3943 if (devices == AUDIO_DEVICE_NONE)
3944 devices = AUDIO_DEVICE_OUT_SPEAKER;
3945
3946 out->flags = flags;
3947 out->devices = devices;
3948 out->dev = adev;
3949 out->format = config->format;
3950 out->sample_rate = config->sample_rate;
3951 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3952 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3953 out->handle = handle;
3954
3955 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3956 if (pcm_profile == NULL) {
3957 ret = -EINVAL;
3958 goto error_open;
3959 }
3960 out->config = pcm_profile->config;
3961
3962 /* Init use case and pcm_config */
3963 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3964 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3965 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3966 ALOGE("%s: Unsupported Offload information", __func__);
3967 ret = -EINVAL;
3968 goto error_open;
3969 }
3970 if (!is_supported_format(config->offload_info.format)) {
3971 ALOGE("%s: Unsupported audio format", __func__);
3972 ret = -EINVAL;
3973 goto error_open;
3974 }
3975
3976 out->compr_config.codec = (struct snd_codec *)
3977 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003978 if (out->compr_config.codec == NULL) {
3979 ret = -ENOMEM;
3980 goto error_open;
3981 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003982
3983 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3984 if (config->offload_info.channel_mask)
3985 out->channel_mask = config->offload_info.channel_mask;
3986 else if (config->channel_mask)
3987 out->channel_mask = config->channel_mask;
3988 out->format = config->offload_info.format;
3989 out->sample_rate = config->offload_info.sample_rate;
3990
3991 out->stream.set_callback = out_set_callback;
3992 out->stream.pause = out_pause;
3993 out->stream.resume = out_resume;
3994 out->stream.drain = out_drain;
3995 out->stream.flush = out_flush;
3996
3997 out->compr_config.codec->id =
3998 get_snd_codec_id(config->offload_info.format);
3999 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
4000 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
4001 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
4002 out->compr_config.codec->bit_rate =
4003 config->offload_info.bit_rate;
4004 out->compr_config.codec->ch_in =
4005 audio_channel_count_from_out_mask(config->channel_mask);
4006 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
4007
4008 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
4009 out->non_blocking = 1;
4010
4011 out->send_new_metadata = 1;
4012 create_offload_callback_thread(out);
4013 out->offload_state = OFFLOAD_STATE_IDLE;
4014
4015 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
4016 __func__, config->offload_info.version,
4017 config->offload_info.bit_rate);
4018 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
4019 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01004020 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004021 out->sample_rate = out->config.rate;
4022 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
4023 } else {
4024 out->usecase = USECASE_AUDIO_PLAYBACK;
4025 out->sample_rate = out->config.rate;
4026 }
4027
4028 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
4029 if (adev->primary_output == NULL)
4030 adev->primary_output = out;
4031 else {
4032 ALOGE("%s: Primary output is already opened", __func__);
4033 ret = -EEXIST;
4034 goto error_open;
4035 }
4036 }
4037
4038 /* Check if this usecase is already existing */
4039 pthread_mutex_lock(&adev->lock);
4040 if (get_usecase_from_id(adev, out->usecase) != NULL) {
4041 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
4042 pthread_mutex_unlock(&adev->lock);
4043 ret = -EEXIST;
4044 goto error_open;
4045 }
4046 pthread_mutex_unlock(&adev->lock);
4047
4048 out->stream.common.get_sample_rate = out_get_sample_rate;
4049 out->stream.common.set_sample_rate = out_set_sample_rate;
4050 out->stream.common.get_buffer_size = out_get_buffer_size;
4051 out->stream.common.get_channels = out_get_channels;
4052 out->stream.common.get_format = out_get_format;
4053 out->stream.common.set_format = out_set_format;
4054 out->stream.common.standby = out_standby;
4055 out->stream.common.dump = out_dump;
4056 out->stream.common.set_parameters = out_set_parameters;
4057 out->stream.common.get_parameters = out_get_parameters;
4058 out->stream.common.add_audio_effect = out_add_audio_effect;
4059 out->stream.common.remove_audio_effect = out_remove_audio_effect;
4060 out->stream.get_latency = out_get_latency;
4061 out->stream.set_volume = out_set_volume;
4062 out->stream.write = out_write;
4063 out->stream.get_render_position = out_get_render_position;
4064 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
4065 out->stream.get_presentation_position = out_get_presentation_position;
4066
4067 out->standby = 1;
4068 /* out->muted = false; by calloc() */
4069 /* out->written = 0; by calloc() */
4070
4071 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
4072 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
4073 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
4074
4075 config->format = out->stream.common.get_format(&out->stream.common);
4076 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4077 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4078
4079 out->is_fastmixer_affinity_set = false;
4080
4081 *stream_out = &out->stream;
4082 ALOGV("%s: exit", __func__);
4083 return 0;
4084
4085error_open:
4086 free(out);
4087 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004088error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004089 ALOGV("%s: exit: ret %d", __func__, ret);
4090 return ret;
4091}
4092
4093static void adev_close_output_stream(struct audio_hw_device *dev,
4094 struct audio_stream_out *stream)
4095{
4096 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004097 (void)dev;
4098
4099 ALOGV("%s: enter", __func__);
4100 out_standby(&stream->common);
4101 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4102 destroy_offload_callback_thread(out);
4103
4104 if (out->compr_config.codec != NULL)
4105 free(out->compr_config.codec);
4106 }
4107 pthread_cond_destroy(&out->cond);
4108 pthread_mutex_destroy(&out->lock);
4109 free(stream);
4110 ALOGV("%s: exit", __func__);
4111}
4112
4113static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4114{
4115 struct audio_device *adev = (struct audio_device *)dev;
4116 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004117 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004118#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004119 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004120#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004121 int ret;
4122
4123 ALOGV("%s: enter: %s", __func__, kvpairs);
4124
4125 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004126
Andreas Schneider05bc1882017-02-09 14:03:11 +01004127 /******************************************************
4128 *** BT SCO
4129 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004130 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4131 if (ret >= 0) {
4132 /* When set to false, HAL should disable EC and NS
4133 * But it is currently not supported.
4134 */
4135 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004136 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004137 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004138 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004139 }
4140
Andreas Schneider05bc1882017-02-09 14:03:11 +01004141 ret = str_parms_get_str(parms,
4142 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4143 value,
4144 sizeof(value));
4145 if (ret >= 0) {
4146 /* TODO: Add support in voice calls */
4147 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4148 adev->voice.bluetooth_wb = true;
4149 ALOGI("%s: Implement support for BT SCO wideband calls!!!",
4150 __func__);
4151 } else {
4152 adev->voice.bluetooth_wb = false;
4153 }
4154 }
4155
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004156 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4157 if (ret >= 0) {
4158 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4159 adev->screen_off = false;
4160 else
4161 adev->screen_off = true;
4162 }
4163
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004164#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004165 ret = str_parms_get_int(parms, "rotation", &val);
4166 if (ret >= 0) {
4167 bool reverse_speakers = false;
4168 switch(val) {
4169 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4170 relative to the user when the device is rotated 90deg from its default rotation. This
4171 assumption is device-specific, not platform-specific like this code. */
4172 case 270:
4173 reverse_speakers = true;
4174 break;
4175 case 0:
4176 case 90:
4177 case 180:
4178 break;
4179 default:
4180 ALOGE("%s: unexpected rotation of %d", __func__, val);
4181 }
4182 pthread_mutex_lock(&adev->lock);
4183 if (adev->speaker_lr_swap != reverse_speakers) {
4184 adev->speaker_lr_swap = reverse_speakers;
4185 /* only update the selected device if there is active pcm playback */
4186 struct audio_usecase *usecase;
4187 struct listnode *node;
4188 list_for_each(node, &adev->usecase_list) {
4189 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4190 if (usecase->type == PCM_PLAYBACK) {
4191 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004192 break;
4193 }
4194 }
4195 }
4196 pthread_mutex_unlock(&adev->lock);
4197 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004198#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004199
4200 str_parms_destroy(parms);
4201
4202 if (ret > 0)
4203 ret = 0;
4204
4205 ALOGV("%s: exit with code(%d)", __func__, ret);
4206 return ret;
4207}
4208
4209static char* adev_get_parameters(const struct audio_hw_device *dev,
4210 const char *keys)
4211{
4212 (void)dev;
4213 (void)keys;
4214
4215 return strdup("");
4216}
4217
4218static int adev_init_check(const struct audio_hw_device *dev)
4219{
4220 (void)dev;
4221
4222 return 0;
4223}
4224
4225static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4226{
4227 int ret = 0;
4228 struct audio_device *adev = (struct audio_device *)dev;
4229 pthread_mutex_lock(&adev->lock);
4230 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004231 adev->voice.volume = volume;
4232 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004233 pthread_mutex_unlock(&adev->lock);
4234 return ret;
4235}
4236
4237static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4238{
4239 (void)dev;
4240 (void)volume;
4241
4242 return -ENOSYS;
4243}
4244
4245static int adev_get_master_volume(struct audio_hw_device *dev,
4246 float *volume)
4247{
4248 (void)dev;
4249 (void)volume;
4250
4251 return -ENOSYS;
4252}
4253
4254static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4255{
4256 (void)dev;
4257 (void)muted;
4258
4259 return -ENOSYS;
4260}
4261
4262static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4263{
4264 (void)dev;
4265 (void)muted;
4266
4267 return -ENOSYS;
4268}
4269
4270static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4271{
4272 struct audio_device *adev = (struct audio_device *)dev;
4273
4274 pthread_mutex_lock(&adev->lock);
4275 if (adev->mode != mode) {
4276 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004277 if (amplifier_set_mode(mode) != 0) {
4278 ALOGE("Failed setting amplifier mode");
4279 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004280 adev->mode = mode;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004281 }
4282 pthread_mutex_unlock(&adev->lock);
4283 return 0;
4284}
4285
4286static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4287{
4288 struct audio_device *adev = (struct audio_device *)dev;
4289 int err = 0;
4290
4291 pthread_mutex_lock(&adev->lock);
4292 adev->mic_mute = state;
4293
4294 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004295 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004296 }
4297
4298 pthread_mutex_unlock(&adev->lock);
4299 return err;
4300}
4301
4302static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4303{
4304 struct audio_device *adev = (struct audio_device *)dev;
4305
4306 *state = adev->mic_mute;
4307
4308 return 0;
4309}
4310
4311static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4312 const struct audio_config *config)
4313{
4314 (void)dev;
4315
4316 /* NOTE: we default to built in mic which may cause a mismatch between what we
4317 * report here and the actual buffer size
4318 */
4319 return get_input_buffer_size(config->sample_rate,
4320 config->format,
4321 audio_channel_count_from_in_mask(config->channel_mask),
4322 PCM_CAPTURE /* usecase_type */,
4323 AUDIO_DEVICE_IN_BUILTIN_MIC);
4324}
4325
4326static int adev_open_input_stream(struct audio_hw_device *dev,
4327 audio_io_handle_t handle __unused,
4328 audio_devices_t devices,
4329 struct audio_config *config,
4330 struct audio_stream_in **stream_in,
4331 audio_input_flags_t flags,
4332 const char *address __unused,
4333 audio_source_t source)
4334{
4335 struct audio_device *adev = (struct audio_device *)dev;
4336 struct stream_in *in;
4337 struct pcm_device_profile *pcm_profile;
4338
4339 ALOGV("%s: enter", __func__);
4340
4341 *stream_in = NULL;
4342 if (check_input_parameters(config->sample_rate, config->format,
4343 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4344 return -EINVAL;
4345
4346 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4347 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4348 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4349 pcm_profile = get_pcm_device(usecase_type, devices);
4350 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4351 // a low latency profile may not exist for that device, fall back
4352 // to regular capture. the MixerThread automatically changes
4353 // to non-fast capture based on the buffer size.
4354 flags &= ~AUDIO_INPUT_FLAG_FAST;
4355 usecase_type = PCM_CAPTURE;
4356 pcm_profile = get_pcm_device(usecase_type, devices);
4357 }
4358 if (pcm_profile == NULL)
4359 return -EINVAL;
4360
4361 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004362 if (in == NULL) {
4363 return -ENOMEM;
4364 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004365
4366 in->stream.common.get_sample_rate = in_get_sample_rate;
4367 in->stream.common.set_sample_rate = in_set_sample_rate;
4368 in->stream.common.get_buffer_size = in_get_buffer_size;
4369 in->stream.common.get_channels = in_get_channels;
4370 in->stream.common.get_format = in_get_format;
4371 in->stream.common.set_format = in_set_format;
4372 in->stream.common.standby = in_standby;
4373 in->stream.common.dump = in_dump;
4374 in->stream.common.set_parameters = in_set_parameters;
4375 in->stream.common.get_parameters = in_get_parameters;
4376 in->stream.common.add_audio_effect = in_add_audio_effect;
4377 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4378 in->stream.set_gain = in_set_gain;
4379 in->stream.read = in_read;
4380 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004381 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004382
4383 in->devices = devices;
4384 in->source = source;
4385 in->dev = adev;
4386 in->standby = 1;
4387 in->main_channels = config->channel_mask;
4388 in->requested_rate = config->sample_rate;
4389 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4390 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4391 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004392 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004393 /* HW codec is limited to default channels. No need to update with
4394 * requested channels */
4395 in->config = pcm_profile->config;
4396
4397 /* Update config params with the requested sample rate and channels */
4398 if (source == AUDIO_SOURCE_HOTWORD) {
4399 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4400 } else {
4401 in->usecase = USECASE_AUDIO_CAPTURE;
4402 }
4403 in->usecase_type = usecase_type;
4404
4405 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4406 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4407
4408 in->is_fastcapture_affinity_set = false;
4409
4410 *stream_in = &in->stream;
4411 ALOGV("%s: exit", __func__);
4412 return 0;
4413}
4414
4415static void adev_close_input_stream(struct audio_hw_device *dev,
4416 struct audio_stream_in *stream)
4417{
4418 struct audio_device *adev = (struct audio_device *)dev;
4419 struct stream_in *in = (struct stream_in*)stream;
4420 ALOGV("%s", __func__);
4421
4422 /* prevent concurrent out_set_parameters, or out_write from standby */
4423 pthread_mutex_lock(&adev->lock_inputs);
4424
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004425 if (in->read_buf) {
4426 free(in->read_buf);
4427 in->read_buf = NULL;
4428 }
4429
4430 if (in->resampler) {
4431 release_resampler(in->resampler);
4432 in->resampler = NULL;
4433 }
4434
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004435#ifdef PREPROCESSING_ENABLED
4436 int i;
4437
4438 for (i=0; i<in->num_preprocessors; i++) {
4439 free(in->preprocessors[i].channel_configs);
4440 }
4441
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004442 if (in->proc_buf_in) {
4443 free(in->proc_buf_in);
4444 in->proc_buf_in = NULL;
4445 }
4446
4447 if (in->proc_buf_out) {
4448 free(in->proc_buf_out);
4449 in->proc_buf_out = NULL;
4450 }
4451
4452 if (in->ref_buf) {
4453 free(in->ref_buf);
4454 in->ref_buf = NULL;
4455 }
4456
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004457#endif
4458
4459 in_standby_l(in);
4460 free(stream);
4461
4462 pthread_mutex_unlock(&adev->lock_inputs);
4463
4464 return;
4465}
4466
4467static int adev_dump(const audio_hw_device_t *device, int fd)
4468{
4469 (void)device;
4470 (void)fd;
4471
4472 return 0;
4473}
4474
4475static int adev_close(hw_device_t *device)
4476{
4477 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004478 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004479 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004480 if (audio_device_ref_count == 0) {
4481 if (amplifier_close() != 0) {
4482 ALOGE("Amplifier close failed");
4483 }
4484 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004485 free(adev->snd_dev_ref_cnt);
4486 free_mixer_list(adev);
4487 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004488
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004489 adev = NULL;
4490
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004491 return 0;
4492}
4493
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004494/* This returns true if the input parameter looks at all plausible as a low latency period size,
4495 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4496 * just that it _might_ work.
4497 */
4498static bool period_size_is_plausible_for_low_latency(int period_size)
4499{
4500 switch (period_size) {
4501 case 64:
4502 case 96:
4503 case 128:
4504 case 192:
4505 case 256:
4506 return true;
4507 default:
4508 return false;
4509 }
4510}
4511
4512static int adev_open(const hw_module_t *module, const char *name,
4513 hw_device_t **device)
4514{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004515 ALOGV("%s: enter", __func__);
4516 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4517
Andreas Schneider56204f62017-01-31 08:17:32 +01004518 *device = NULL;
4519
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004520 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004521 if (adev == NULL) {
4522 return -ENOMEM;
4523 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004524
4525 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4526 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4527 adev->device.common.module = (struct hw_module_t *)module;
4528 adev->device.common.close = adev_close;
4529
4530 adev->device.init_check = adev_init_check;
4531 adev->device.set_voice_volume = adev_set_voice_volume;
4532 adev->device.set_master_volume = adev_set_master_volume;
4533 adev->device.get_master_volume = adev_get_master_volume;
4534 adev->device.set_master_mute = adev_set_master_mute;
4535 adev->device.get_master_mute = adev_get_master_mute;
4536 adev->device.set_mode = adev_set_mode;
4537 adev->device.set_mic_mute = adev_set_mic_mute;
4538 adev->device.get_mic_mute = adev_get_mic_mute;
4539 adev->device.set_parameters = adev_set_parameters;
4540 adev->device.get_parameters = adev_get_parameters;
4541 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4542 adev->device.open_output_stream = adev_open_output_stream;
4543 adev->device.close_output_stream = adev_close_output_stream;
4544 adev->device.open_input_stream = adev_open_input_stream;
4545 adev->device.close_input_stream = adev_close_input_stream;
4546 adev->device.dump = adev_dump;
4547
4548 /* Set the default route before the PCM stream is opened */
4549 adev->mode = AUDIO_MODE_NORMAL;
4550 adev->active_input = NULL;
4551 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004552
4553 adev->voice.volume = 1.0f;
4554 adev->voice.bluetooth_nrec = true;
4555 adev->voice.in_call = false;
4556
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004557 /* adev->cur_hdmi_channels = 0; by calloc() */
4558 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004559 if (adev->snd_dev_ref_cnt == NULL) {
4560 free(adev);
4561 return -ENOMEM;
4562 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004563
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004564 adev->ns_in_voice_rec = false;
4565
4566 list_init(&adev->usecase_list);
4567
4568 if (mixer_init(adev) != 0) {
4569 free(adev->snd_dev_ref_cnt);
4570 free(adev);
4571 ALOGE("%s: Failed to init, aborting.", __func__);
4572 *device = NULL;
4573 return -EINVAL;
4574 }
4575
4576 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4577 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4578 if (adev->offload_fx_lib == NULL) {
4579 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4580 } else {
4581 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4582 adev->offload_fx_start_output =
4583 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4584 "visualizer_hal_start_output");
4585 adev->offload_fx_stop_output =
4586 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4587 "visualizer_hal_stop_output");
4588 }
4589 }
4590
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004591 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4592 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4593 if (adev->sound_trigger_lib == NULL) {
4594 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4595 } else {
4596 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4597 adev->sound_trigger_open_for_streaming =
4598 (int (*)(void))dlsym(adev->sound_trigger_lib,
4599 "sound_trigger_open_for_streaming");
4600 adev->sound_trigger_read_samples =
4601 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4602 "sound_trigger_read_samples");
4603 adev->sound_trigger_close_for_streaming =
4604 (int (*)(int))dlsym(adev->sound_trigger_lib,
4605 "sound_trigger_close_for_streaming");
4606 if (!adev->sound_trigger_open_for_streaming ||
4607 !adev->sound_trigger_read_samples ||
4608 !adev->sound_trigger_close_for_streaming) {
4609
4610 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4611 adev->sound_trigger_open_for_streaming = 0;
4612 adev->sound_trigger_read_samples = 0;
4613 adev->sound_trigger_close_for_streaming = 0;
4614 }
4615 }
4616 }
4617
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004618 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004619 if (adev->voice.session == NULL) {
4620 ALOGE("%s: Failed to initialize voice session data", __func__);
4621
4622 free(adev->snd_dev_ref_cnt);
4623 free(adev);
4624
4625 *device = NULL;
4626 return -EINVAL;
4627 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004628
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004629 if (amplifier_open() != 0) {
4630 ALOGE("Amplifier initialization failed");
4631 }
4632
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004633 *device = &adev->device.common;
4634
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004635 audio_device_ref_count++;
4636
4637 char value[PROPERTY_VALUE_MAX];
4638 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4639 int trial = atoi(value);
4640 if (period_size_is_plausible_for_low_latency(trial)) {
4641
4642 pcm_device_playback.config.period_size = trial;
4643 pcm_device_playback.config.start_threshold =
4644 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4645 pcm_device_playback.config.stop_threshold =
4646 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4647
4648 pcm_device_capture_low_latency.config.period_size = trial;
4649 }
4650 }
4651
4652 ALOGV("%s: exit", __func__);
4653 return 0;
4654}
4655
4656static struct hw_module_methods_t hal_module_methods = {
4657 .open = adev_open,
4658};
4659
4660struct audio_module HAL_MODULE_INFO_SYM = {
4661 .common = {
4662 .tag = HARDWARE_MODULE_TAG,
4663 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4664 .hal_api_version = HARDWARE_HAL_API_VERSION,
4665 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004666 .name = "Samsung Audio HAL",
4667 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004668 .methods = &hal_module_methods,
4669 },
4670};