blob: ce452efc036bf6324699ed4a63a33c81b8a391d1 [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>
stenkinevgeniy44335362018-05-07 18:00:13 +00005 * Copyright (C) 2018 The LineageOS Project
Christopher N. Hesse297a6362017-01-28 12:40:45 +01006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "audio_hw_primary"
21/*#define LOG_NDEBUG 0*/
22/*#define VERY_VERY_VERBOSE_LOGGING*/
23#ifdef VERY_VERY_VERBOSE_LOGGING
24#define ALOGVV ALOGV
25#else
26#define ALOGVV(a...) do { } while(0)
27#endif
28
29#define _GNU_SOURCE
30#include <errno.h>
31#include <pthread.h>
32#include <stdint.h>
33#include <sys/time.h>
34#include <stdlib.h>
35#include <math.h>
36#include <dlfcn.h>
Christopher N. Hesse297a6362017-01-28 12:40:45 +010037
38#include <cutils/log.h>
39#include <cutils/str_parms.h>
40#include <cutils/atomic.h>
41#include <cutils/sched_policy.h>
42#include <cutils/properties.h>
43
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010044#include <samsung_audio.h>
45
Christopher N. Hesse297a6362017-01-28 12:40:45 +010046#include <hardware/audio_effect.h>
47#include <system/thread_defs.h>
48#include <audio_effects/effect_aec.h>
49#include <audio_effects/effect_ns.h>
50#include "audio_hw.h"
Christopher N. Hesse757ac412017-01-28 14:42:48 +010051#include "compress_offload.h"
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +010052#include "voice.h"
Christopher N. Hesse297a6362017-01-28 12:40:45 +010053
54#include "sound/compress_params.h"
55
Christopher N. Hesse297a6362017-01-28 12:40:45 +010056
57/* TODO: the following PCM device profiles could be read from a config file */
58static struct pcm_device_profile pcm_device_playback = {
59 .config = {
60 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
61 .rate = PLAYBACK_DEFAULT_SAMPLING_RATE,
62 .period_size = PLAYBACK_PERIOD_SIZE,
63 .period_count = PLAYBACK_PERIOD_COUNT,
64 .format = PCM_FORMAT_S16_LE,
65 .start_threshold = PLAYBACK_START_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
66 .stop_threshold = PLAYBACK_STOP_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
67 .silence_threshold = 0,
68 .silence_size = UINT_MAX,
69 .avail_min = PLAYBACK_AVAILABLE_MIN,
70 },
71 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010072 .id = SOUND_PLAYBACK_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010073 .type = PCM_PLAYBACK,
74 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010075 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010076};
77
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010078static struct pcm_device_profile pcm_device_deep_buffer = {
79 .config = {
80 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
81 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
82 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
83 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
84 .format = PCM_FORMAT_S16_LE,
85 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
86 .stop_threshold = INT_MAX,
87 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
88 },
89 .card = SOUND_CARD,
90 .id = SOUND_DEEP_BUFFER_DEVICE,
91 .type = PCM_PLAYBACK,
92 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010093 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010094};
95
Christopher N. Hesse297a6362017-01-28 12:40:45 +010096static struct pcm_device_profile pcm_device_capture = {
97 .config = {
98 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
99 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
100 .period_size = CAPTURE_PERIOD_SIZE,
101 .period_count = CAPTURE_PERIOD_COUNT,
102 .format = PCM_FORMAT_S16_LE,
103 .start_threshold = CAPTURE_START_THRESHOLD,
104 .stop_threshold = 0,
105 .silence_threshold = 0,
106 .avail_min = 0,
107 },
108 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100109 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100110 .type = PCM_CAPTURE,
111 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
112};
113
114static struct pcm_device_profile pcm_device_capture_low_latency = {
115 .config = {
116 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
117 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
118 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
119 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
120 .format = PCM_FORMAT_S16_LE,
121 .start_threshold = CAPTURE_START_THRESHOLD,
122 .stop_threshold = 0,
123 .silence_threshold = 0,
124 .avail_min = 0,
125 },
126 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100127 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100128 .type = PCM_CAPTURE_LOW_LATENCY,
129 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
130};
131
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100132#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100133static struct pcm_device_profile pcm_device_capture_loopback_aec = {
134 .config = {
135 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
136 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
137 .period_size = CAPTURE_PERIOD_SIZE,
138 .period_count = CAPTURE_PERIOD_COUNT,
139 .format = PCM_FORMAT_S16_LE,
140 .start_threshold = CAPTURE_START_THRESHOLD,
141 .stop_threshold = 0,
142 .silence_threshold = 0,
143 .avail_min = 0,
144 },
145 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100146 .id = SOUND_CAPTURE_LOOPBACK_AEC_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100147 .type = PCM_CAPTURE,
148 .devices = SND_DEVICE_IN_LOOPBACK_AEC,
149};
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100150#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100151
152static struct pcm_device_profile pcm_device_playback_sco = {
153 .config = {
154 .channels = SCO_DEFAULT_CHANNEL_COUNT,
155 .rate = SCO_DEFAULT_SAMPLING_RATE,
156 .period_size = SCO_PERIOD_SIZE,
157 .period_count = SCO_PERIOD_COUNT,
158 .format = PCM_FORMAT_S16_LE,
159 .start_threshold = SCO_START_THRESHOLD,
160 .stop_threshold = SCO_STOP_THRESHOLD,
161 .silence_threshold = 0,
162 .avail_min = SCO_AVAILABLE_MIN,
163 },
164 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100165 .id = SOUND_PLAYBACK_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100166 .type = PCM_PLAYBACK,
167 .devices =
168 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
169 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
170};
171
172static struct pcm_device_profile pcm_device_capture_sco = {
173 .config = {
174 .channels = SCO_DEFAULT_CHANNEL_COUNT,
175 .rate = SCO_DEFAULT_SAMPLING_RATE,
176 .period_size = SCO_PERIOD_SIZE,
177 .period_count = SCO_PERIOD_COUNT,
178 .format = PCM_FORMAT_S16_LE,
179 .start_threshold = CAPTURE_START_THRESHOLD,
180 .stop_threshold = 0,
181 .silence_threshold = 0,
182 .avail_min = 0,
183 },
184 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100185 .id = SOUND_CAPTURE_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100186 .type = PCM_CAPTURE,
187 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
188};
189
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100190static struct pcm_device_profile * const pcm_devices[] = {
191 &pcm_device_playback,
192 &pcm_device_capture,
193 &pcm_device_capture_low_latency,
194 &pcm_device_playback_sco,
195 &pcm_device_capture_sco,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100196#ifdef SOUND_CAPTURE_LOOPBACK_AEC_DEVICE
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100197 &pcm_device_capture_loopback_aec,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100198#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100199 NULL,
200};
201
202static const char * const use_case_table[AUDIO_USECASE_MAX] = {
203 [USECASE_AUDIO_PLAYBACK] = "playback",
204 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
205 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
Andreas Schneiderdf6fc8a2017-02-14 11:38:41 +0100206 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback deep-buffer",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100207 [USECASE_AUDIO_CAPTURE] = "capture",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100208 [USECASE_VOICE_CALL] = "voice-call",
209};
210
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100211#define STRING_TO_ENUM(string) { #string, string }
212
213static unsigned int audio_device_ref_count;
214
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100215struct string_to_enum {
216 const char *name;
217 uint32_t value;
218};
219
220static const struct string_to_enum out_channels_name_to_enum_table[] = {
221 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
222 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
223 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
224};
225
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200226static struct audio_device *adev = NULL;
227
228static amplifier_device_t * get_amplifier_device(void)
229{
230 if (adev)
231 return adev->amp;
232
233 return NULL;
234}
235
236static int amplifier_open(void)
237{
238 int rc;
239 amplifier_module_t *module;
240
241 rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
242 (const hw_module_t **) &module);
243 if (rc) {
244 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
245 __func__, strerror(-rc));
246 return -ENODEV;
247 }
248
249 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
250 if (rc) {
251 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
252 __func__, strerror(-rc));
253 return -ENODEV;
254 }
255
256 return 0;
257}
258
259static int amplifier_set_input_devices(uint32_t devices)
260{
261 amplifier_device_t *amp = get_amplifier_device();
262 if (amp && amp->set_input_devices)
263 return amp->set_input_devices(amp, devices);
264
265 return 0;
266}
267
268static int amplifier_set_output_devices(uint32_t devices)
269{
270 amplifier_device_t *amp = get_amplifier_device();
271 if (amp && amp->set_output_devices)
272 return amp->set_output_devices(amp, devices);
273
274 return 0;
275}
276
277static int amplifier_enable_devices(uint32_t devices, bool enable)
278{
279 amplifier_device_t *amp = get_amplifier_device();
280 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
281 devices < SND_DEVICE_OUT_END;
282
283 if (amp && amp->enable_output_devices && is_output)
284 return amp->enable_output_devices(amp, devices, enable);
285
286 if (amp && amp->enable_input_devices && !is_output)
287 return amp->enable_input_devices(amp, devices, enable);
288
289 return 0;
290}
291
292static int amplifier_set_mode(audio_mode_t mode)
293{
294 amplifier_device_t *amp = get_amplifier_device();
295 if (amp && amp->set_mode)
296 return amp->set_mode(amp, mode);
297
298 return 0;
299}
300
301static int amplifier_output_stream_start(struct audio_stream_out *stream,
302 bool offload)
303{
304 amplifier_device_t *amp = get_amplifier_device();
305 if (amp && amp->output_stream_start)
306 return amp->output_stream_start(amp, stream, offload);
307
308 return 0;
309}
310
311static int amplifier_input_stream_start(struct audio_stream_in *stream)
312{
313 amplifier_device_t *amp = get_amplifier_device();
314 if (amp && amp->input_stream_start)
315 return amp->input_stream_start(amp, stream);
316
317 return 0;
318}
319
320static int amplifier_output_stream_standby(struct audio_stream_out *stream)
321{
322 amplifier_device_t *amp = get_amplifier_device();
323 if (amp && amp->output_stream_standby)
324 return amp->output_stream_standby(amp, stream);
325
326 return 0;
327}
328
329static int amplifier_input_stream_standby(struct audio_stream_in *stream)
330{
331 amplifier_device_t *amp = get_amplifier_device();
332 if (amp && amp->input_stream_standby)
333 return amp->input_stream_standby(amp, stream);
334
335 return 0;
336}
337
338static int amplifier_set_parameters(struct str_parms *parms)
339{
340 amplifier_device_t *amp = get_amplifier_device();
341 if (amp && amp->set_parameters)
342 return amp->set_parameters(amp, parms);
343
344 return 0;
345}
346
347static int amplifier_close(void)
348{
349 amplifier_device_t *amp = get_amplifier_device();
350 if (amp)
351 amplifier_device_close(amp);
352
353 return 0;
354}
355
Andreas Schneider759368f2017-02-02 16:11:14 +0100356struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
357 struct timespec ret;
358 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100359
360 if (time0.tv_nsec > time1.tv_nsec) {
361 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
362 time0.tv_nsec -= (long int) (1E9 * xsec);
363 time0.tv_sec += xsec;
364 }
365
366 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
367 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
368 time0.tv_nsec += (long int) (1E9 * xsec);
369 time0.tv_sec -= xsec;
370 }
371
Paul Keithf114e2e2017-02-14 20:41:33 -0600372 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
373 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100374
375 return ret;
376}
377
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100378static bool is_supported_format(audio_format_t format)
379{
380 if (format == AUDIO_FORMAT_MP3 ||
381 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
382 return true;
383
384 return false;
385}
386
387static int get_snd_codec_id(audio_format_t format)
388{
389 int id = 0;
390
391 switch (format & AUDIO_FORMAT_MAIN_MASK) {
392 case AUDIO_FORMAT_MP3:
393 id = SND_AUDIOCODEC_MP3;
394 break;
395 case AUDIO_FORMAT_AAC:
396 id = SND_AUDIOCODEC_AAC;
397 break;
398 default:
399 ALOGE("%s: Unsupported audio format", __func__);
400 }
401
402 return id;
403}
404
405/* Array to store sound devices */
406static const char * const device_table[SND_DEVICE_MAX] = {
407 [SND_DEVICE_NONE] = "none",
408 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100409 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100410 [SND_DEVICE_OUT_SPEAKER] = "speaker",
411 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
412 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100413 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100414 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100415 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100416 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100417 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100418 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100419 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
420 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100421 [SND_DEVICE_OUT_HDMI] = "hdmi",
422 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
423 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100424
425 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100426 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100427 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
428 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100429 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100430 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
431 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100432 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
433 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100434 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100435 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100436 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100437 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100438 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100439 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
440 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100441 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
442 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
443 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100444 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
445 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100446 [SND_DEVICE_IN_LOOPBACK_AEC] = "loopback-aec",
447};
448
449static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
450{
451 struct mixer_card *mixer_card;
452 struct listnode *node;
453
454 list_for_each(node, &adev->mixer_list) {
455 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
456 if (mixer_card->card == card)
457 return mixer_card;
458 }
459 return NULL;
460}
461
462static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
463{
464 struct mixer_card *mixer_card;
465 struct listnode *node;
466
467 list_for_each(node, &usecase->mixer_list) {
468 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
469 if (mixer_card->card == card)
470 return mixer_card;
471 }
472 return NULL;
473}
474
475static void free_mixer_list(struct audio_device *adev)
476{
477 struct mixer_card *mixer_card;
478 struct listnode *node;
479 struct listnode *next;
480
481 list_for_each_safe(node, next, &adev->mixer_list) {
482 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
483 list_remove(node);
484 audio_route_free(mixer_card->audio_route);
485 free(mixer_card);
486 }
487}
488
489static int mixer_init(struct audio_device *adev)
490{
491 int i;
492 int card;
493 int retry_num;
494 struct mixer *mixer;
495 struct audio_route *audio_route;
496 char mixer_path[PATH_MAX];
497 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100498 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100499
500 list_init(&adev->mixer_list);
501
502 for (i = 0; pcm_devices[i] != NULL; i++) {
503 card = pcm_devices[i]->card;
504 if (adev_get_mixer_for_card(adev, card) == NULL) {
505 retry_num = 0;
506 do {
507 mixer = mixer_open(card);
508 if (mixer == NULL) {
509 if (++retry_num > RETRY_NUMBER) {
510 ALOGE("%s unable to open the mixer for--card %d, aborting.",
511 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100512 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100513 goto error;
514 }
515 usleep(RETRY_US);
516 }
517 } while (mixer == NULL);
518
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100519 sprintf(mixer_path, "/vendor/etc/mixer_paths_%d.xml", card);
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100520 if (access(mixer_path, F_OK) == -1) {
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100521 ALOGW("%s: Failed to open mixer paths from %s, retrying with legacy location",
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100522 __func__, mixer_path);
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100523 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
524 if (access(mixer_path, F_OK) == -1) {
525 ALOGE("%s: Failed to load a mixer paths configuration, your system will crash",
526 __func__);
527 }
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100528 }
529
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100530 audio_route = audio_route_init(card, mixer_path);
531 if (!audio_route) {
532 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
533 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100534 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100535 goto error;
536 }
537 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100538 if (mixer_card == NULL) {
539 ret = -ENOMEM;
540 goto error;
541 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100542 mixer_card->card = card;
543 mixer_card->mixer = mixer;
544 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100545
546 /* Do not sleep on first enable_snd_device() */
547 mixer_card->dsp_poweroff_time.tv_sec = 1;
548 mixer_card->dsp_poweroff_time.tv_nsec = 0;
549
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100550 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
551 }
552 }
553
554 return 0;
555
556error:
557 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100558 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100559}
560
561static const char *get_snd_device_name(snd_device_t snd_device)
562{
563 const char *name = NULL;
564
Andreas Schneideradb788d2017-02-13 15:19:36 +0100565 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100566 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100567 name = device_table[snd_device];
568
569 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
570
571 return name;
572}
573
574static const char *get_snd_device_display_name(snd_device_t snd_device)
575{
576 const char *name = get_snd_device_name(snd_device);
577
578 if (name == NULL)
579 name = "SND DEVICE NOT FOUND";
580
581 return name;
582}
583
584static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
585{
586 int i;
587
588 devices &= ~AUDIO_DEVICE_BIT_IN;
589 for (i = 0; pcm_devices[i] != NULL; i++) {
590 if ((pcm_devices[i]->type == uc_type) &&
591 (devices & pcm_devices[i]->devices))
592 break;
593 }
594 return pcm_devices[i];
595}
596
597static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
598 audio_usecase_t uc_id)
599{
600 struct audio_usecase *usecase;
601 struct listnode *node;
602
603 list_for_each(node, &adev->usecase_list) {
604 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
605 if (usecase->id == uc_id)
606 return usecase;
607 }
608 return NULL;
609}
610
611static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
612 usecase_type_t type)
613{
614 struct audio_usecase *usecase;
615 struct listnode *node;
616
617 list_for_each(node, &adev->usecase_list) {
618 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
619 if (usecase->type & type)
620 return usecase;
621 }
622 return NULL;
623}
624
625/* always called with adev lock held */
626static int set_voice_volume_l(struct audio_device *adev, float volume)
627{
628 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100629
630 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100631 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100632 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100633
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100634 return err;
635}
636
637
638static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
639{
640
641 audio_mode_t mode = adev->mode;
642 snd_device_t snd_device = SND_DEVICE_NONE;
643
644 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
645 if (devices == AUDIO_DEVICE_NONE ||
646 devices & AUDIO_DEVICE_BIT_IN) {
647 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
648 goto exit;
649 }
650
651 if (mode == AUDIO_MODE_IN_CALL) {
652 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
653 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100654 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300655 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100656 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100657 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
658 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
659 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100660 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100661 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100662
663 if (voice_session_uses_wideband(adev->voice.session)) {
664 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
665 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
666 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300667 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100668 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100669 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
670 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
671 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
672 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
673 }
674 }
675
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100676 if (snd_device != SND_DEVICE_NONE) {
677 goto exit;
678 }
679 }
680
681 if (popcount(devices) == 2) {
682 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
683 AUDIO_DEVICE_OUT_SPEAKER)) {
684 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
685 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
686 AUDIO_DEVICE_OUT_SPEAKER)) {
687 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
688 } else {
689 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
690 goto exit;
691 }
692 if (snd_device != SND_DEVICE_NONE) {
693 goto exit;
694 }
695 }
696
697 if (popcount(devices) != 1) {
698 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
699 goto exit;
700 }
701
702 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
703 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
704 snd_device = SND_DEVICE_OUT_HEADPHONES;
705 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
706 snd_device = SND_DEVICE_OUT_SPEAKER;
707 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
708 snd_device = SND_DEVICE_OUT_BT_SCO;
709 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100710 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100711 } else {
712 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
713 }
714exit:
715 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
716 return snd_device;
717}
718
719static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
720{
721 audio_source_t source;
722 audio_mode_t mode = adev->mode;
723 audio_devices_t in_device;
724 audio_channel_mask_t channel_mask;
725 snd_device_t snd_device = SND_DEVICE_NONE;
726 struct stream_in *active_input = NULL;
727 struct audio_usecase *usecase;
728
729 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
730 if (usecase != NULL) {
731 active_input = (struct stream_in *)usecase->stream;
732 }
733 source = (active_input == NULL) ?
734 AUDIO_SOURCE_DEFAULT : active_input->source;
735
Andreas Schneider757e2d82017-02-10 19:28:35 +0100736 in_device = (active_input == NULL) ?
737 AUDIO_DEVICE_NONE :
738 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100739 channel_mask = (active_input == NULL) ?
740 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
741
742 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
743 __func__, out_device, in_device);
744 if (mode == AUDIO_MODE_IN_CALL) {
745 if (out_device == AUDIO_DEVICE_NONE) {
746 ALOGE("%s: No output device set for voice call", __func__);
747 goto exit;
748 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100749
Andreas Schneider82f32482017-02-06 09:00:48 +0100750 snd_device = SND_DEVICE_IN_VOICE_MIC;
751 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100752 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100753 }
754
755 if (voice_session_uses_twomic(adev->voice.session)) {
756 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
757 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
758 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
759 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
760 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
761 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100762 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100763
764 if (voice_session_uses_wideband(adev->voice.session)) {
765 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
766 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
767 }
768
769 if (voice_session_uses_twomic(adev->voice.session)) {
770 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
771 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
772 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
773 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
774 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
775 }
776 }
777 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100778
779 /* BT SCO */
780 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
781 snd_device = SND_DEVICE_IN_VOICE_MIC;
782
783 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300784 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100785 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300786 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100787 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300788 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100789 } else if (voice_session_uses_twomic(adev->voice.session)) {
790 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
791 }
792 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100793 } else if (source == AUDIO_SOURCE_CAMCORDER) {
794 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
795 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
796 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
797 }
798 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
799 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100800 if (snd_device == SND_DEVICE_NONE) {
801 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
802 }
803 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
804 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
805 }
806 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
807 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
808 in_device = AUDIO_DEVICE_IN_BACK_MIC;
809 if (active_input) {
810 if (active_input->enable_aec) {
811 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
812 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
813 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
814 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
815 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
816 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100817 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100818 }
819 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
820 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
821 }
822 }
823 /* TODO: set echo reference */
824 }
825 } else if (source == AUDIO_SOURCE_DEFAULT) {
826 goto exit;
827 }
828
829
830 if (snd_device != SND_DEVICE_NONE) {
831 goto exit;
832 }
833
834 if (in_device != AUDIO_DEVICE_NONE &&
835 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
836 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
837 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100838 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100839 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
840 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
841 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
842 snd_device = SND_DEVICE_IN_HEADSET_MIC;
843 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
844 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
845 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
846 snd_device = SND_DEVICE_IN_HDMI_MIC;
847 } else {
848 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100849 ALOGW("%s: Using default earpiece-mic", __func__);
850 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100851 }
852 } else {
853 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100854 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100855 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
856 snd_device = SND_DEVICE_IN_HEADSET_MIC;
857 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
858 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
859 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100860 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100861 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
862 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
863 } else {
864 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100865 ALOGW("%s: Using default earpiece-mic", __func__);
866 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100867 }
868 }
869exit:
870 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
871 return snd_device;
872}
873
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100874#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100875static int set_hdmi_channels(struct audio_device *adev, int channel_count)
876{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100877 (void)adev;
878 (void)channel_count;
879 /* TODO */
880
881 return 0;
882}
883
884static int edid_get_max_channels(struct audio_device *adev)
885{
886 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100887 (void)adev;
888
889 /* TODO */
890 return max_channels;
891}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100892#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100893
894/* Delay in Us */
895static int64_t render_latency(audio_usecase_t usecase)
896{
897 (void)usecase;
898 /* TODO */
899 return 0;
900}
901
902static int enable_snd_device(struct audio_device *adev,
903 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100904 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100905{
906 struct mixer_card *mixer_card;
907 struct listnode *node;
908 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100909#ifdef DSP_POWEROFF_DELAY
910 struct timespec activation_time;
911 struct timespec elapsed_time;
912#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100913
914 if (snd_device_name == NULL)
915 return -EINVAL;
916
917 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
918 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100919 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
920 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100921 return 0;
922 }
923 adev->snd_dev_ref_cnt[snd_device]++;
924 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
925 ALOGV("%s: snd_device(%d: %s) is already active",
926 __func__, snd_device, snd_device_name);
927 return 0;
928 }
929
930 ALOGV("%s: snd_device(%d: %s)", __func__,
931 snd_device, snd_device_name);
932
933 list_for_each(node, &uc_info->mixer_list) {
934 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100935
936#ifdef DSP_POWEROFF_DELAY
937 clock_gettime(CLOCK_MONOTONIC, &activation_time);
938
Andreas Schneider58735a92017-02-13 16:48:17 +0100939 elapsed_time = time_spec_diff(activation_time,
940 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100941 if (elapsed_time.tv_sec == 0) {
942 long elapsed_usec = elapsed_time.tv_nsec / 1000;
943
944 if (elapsed_usec < DSP_POWEROFF_DELAY) {
945 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
946 }
947 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100948#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200949
950 amplifier_enable_devices(snd_device, true);
951
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100952 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100953 }
954
955 return 0;
956}
957
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100958int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100959 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100960 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100961{
962 struct mixer_card *mixer_card;
963 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100964 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100965 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100966 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100967
968 if (snd_device_name == NULL)
969 return -EINVAL;
970
971 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
972 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100973 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
974 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100975 return 0;
976 }
977
978 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
979 ALOGE("%s: device ref cnt is already 0", __func__);
980 return -EINVAL;
981 }
982 adev->snd_dev_ref_cnt[snd_device]--;
983 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
984 ALOGV("%s: snd_device(%d: %s)", __func__,
985 snd_device, snd_device_name);
986 list_for_each(node, &uc_info->mixer_list) {
987 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100988 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +0100989 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100990 /*
991 * Cycle the rx device to eliminate routing conflicts.
992 * This prevents issues when an input route shares mixer controls with an output
993 * route.
994 */
995 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100996 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100997 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200998
999 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +01001000#ifdef DSP_POWEROFF_DELAY
1001 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
1002#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001003 }
1004 }
1005 return 0;
1006}
1007
1008static int select_devices(struct audio_device *adev,
1009 audio_usecase_t uc_id)
1010{
1011 snd_device_t out_snd_device = SND_DEVICE_NONE;
1012 snd_device_t in_snd_device = SND_DEVICE_NONE;
1013 struct audio_usecase *usecase = NULL;
1014 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001015 struct stream_in *active_input = NULL;
1016 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001017
1018 ALOGV("%s: usecase(%d)", __func__, uc_id);
1019
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001020 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1021 if (usecase != NULL) {
1022 active_input = (struct stream_in *)usecase->stream;
1023 }
1024
1025 usecase = get_usecase_from_id(adev, uc_id);
1026 if (usecase == NULL) {
1027 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1028 return -EINVAL;
1029 }
1030 active_out = (struct stream_out *)usecase->stream;
1031
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001032
1033 /*
1034 * If the voice call is active, use the sound devices of voice call usecase
1035 * so that it would not result any device switch. All the usecases will
1036 * be switched to new device when select_devices() is called for voice call
1037 * usecase.
1038 */
1039 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1040 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1041 if (vc_usecase == NULL) {
1042 ALOGE("%s: Could not find the voice call usecase", __func__);
1043 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001044 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1045 get_snd_device_display_name(vc_usecase->out_snd_device),
1046 get_snd_device_display_name(vc_usecase->in_snd_device));
1047 usecase->devices = vc_usecase->devices;
1048 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001049 }
1050 }
1051
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001052 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001053 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001054 prepare_voice_session(adev->voice.session, active_out->devices);
1055 out_snd_device = get_output_snd_device(adev, active_out->devices);
1056 in_snd_device = get_input_snd_device(adev, active_out->devices);
1057 } else if (usecase->type == PCM_PLAYBACK) {
1058 usecase->devices = active_out->devices;
1059 in_snd_device = SND_DEVICE_NONE;
1060 if (out_snd_device == SND_DEVICE_NONE) {
1061 out_snd_device = get_output_snd_device(adev, active_out->devices);
1062 if (active_out == adev->primary_output &&
1063 active_input &&
1064 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1065 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001066 }
1067 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001068 } else if (usecase->type == PCM_CAPTURE) {
1069 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1070 out_snd_device = SND_DEVICE_NONE;
1071 if (in_snd_device == SND_DEVICE_NONE) {
1072 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1073 adev->primary_output && !adev->primary_output->standby) {
1074 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1075 } else {
1076 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001077 }
1078 }
1079 }
1080
1081 if (out_snd_device == usecase->out_snd_device &&
1082 in_snd_device == usecase->in_snd_device) {
1083 return 0;
1084 }
1085
1086 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1087 out_snd_device, get_snd_device_display_name(out_snd_device),
1088 in_snd_device, get_snd_device_display_name(in_snd_device));
1089
1090
1091 /* Disable current sound devices */
1092 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001093 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001094 }
1095
1096 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001097 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001098 }
1099
1100 /* Enable new sound devices */
1101 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001102 /* We need to update the audio path if we switch the out devices */
1103 if (adev->voice.in_call) {
1104 set_voice_session_audio_path(adev->voice.session);
1105 }
1106
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001107 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001108 }
1109
1110 if (in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001111 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001112 }
1113
1114 usecase->in_snd_device = in_snd_device;
1115 usecase->out_snd_device = out_snd_device;
1116
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001117 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1118 amplifier_set_input_devices(in_snd_device);
1119 amplifier_set_output_devices(out_snd_device);
1120
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001121 return 0;
1122}
1123
1124
1125static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1126static int do_in_standby_l(struct stream_in *in);
1127
1128#ifdef PREPROCESSING_ENABLED
1129static void get_capture_reference_delay(struct stream_in *in,
1130 size_t frames __unused,
1131 struct echo_reference_buffer *buffer)
1132{
1133 ALOGVV("%s: enter:)", __func__);
1134
1135 /* read frames available in kernel driver buffer */
1136 unsigned int kernel_frames;
1137 struct timespec tstamp;
1138 long buf_delay;
1139 long kernel_delay;
1140 long delay_ns;
1141 struct pcm_device *ref_device;
1142 long rsmp_delay = 0;
1143
1144 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1145 struct pcm_device, stream_list_node);
1146
1147 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1148 buffer->time_stamp.tv_sec = 0;
1149 buffer->time_stamp.tv_nsec = 0;
1150 buffer->delay_ns = 0;
1151 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1152 return;
1153 }
1154
1155 /* adjust render time stamp with delay added by current driver buffer.
1156 * Add the duration of current frame as we want the render time of the last
1157 * sample being written. */
1158
1159 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1160
1161 buffer->time_stamp = tstamp;
1162 buffer->delay_ns = kernel_delay;
1163
1164 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1165 " delay_ns: [%d] , frames:[%zd]",
1166 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1167}
1168
1169static void get_capture_delay(struct stream_in *in,
1170 size_t frames __unused,
1171 struct echo_reference_buffer *buffer)
1172{
1173 ALOGVV("%s: enter:)", __func__);
1174 /* read frames available in kernel driver buffer */
1175 unsigned int kernel_frames;
1176 struct timespec tstamp;
1177 long buf_delay;
1178 long rsmp_delay;
1179 long kernel_delay;
1180 long delay_ns;
1181 struct pcm_device *pcm_device;
1182
1183 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1184 struct pcm_device, stream_list_node);
1185
1186 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1187 buffer->time_stamp.tv_sec = 0;
1188 buffer->time_stamp.tv_nsec = 0;
1189 buffer->delay_ns = 0;
1190 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1191 return;
1192 }
1193
1194 /* read frames available in audio HAL input buffer
1195 * add number of frames being read as we want the capture time of first sample
1196 * in current buffer */
1197 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1198 * at requested sampling rate */
1199 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1200 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1201
1202 /* add delay introduced by resampler */
1203 rsmp_delay = 0;
1204 if (in->resampler) {
1205 rsmp_delay = in->resampler->delay_ns(in->resampler);
1206 }
1207
1208 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1209
1210 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1211
1212 buffer->time_stamp = tstamp;
1213 buffer->delay_ns = delay_ns;
1214 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1215 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1216 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1217 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1218 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1219 in->read_buf_frames, in->proc_buf_frames, frames);
1220}
1221
1222static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1223{
1224 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1225 struct echo_reference_buffer b;
1226 b.delay_ns = 0;
1227 struct pcm_device *pcm_device;
1228
1229 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1230 struct pcm_device, stream_list_node);
1231
1232 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1233 "b.frame_count = [%zd]",
1234 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1235 if (in->ref_buf_frames < frames) {
1236 if (in->ref_buf_size < frames) {
1237 in->ref_buf_size = frames;
1238 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1239 ALOG_ASSERT((in->ref_buf != NULL),
1240 "update_echo_reference() failed to reallocate ref_buf");
1241 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1242 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1243 }
1244 b.frame_count = frames - in->ref_buf_frames;
1245 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1246
1247 get_capture_delay(in, frames, &b);
1248
1249 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1250 {
1251 in->ref_buf_frames += b.frame_count;
1252 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1253 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1254 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1255 }
1256 } else
1257 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1258 return b.delay_ns;
1259}
1260
1261static int set_preprocessor_param(effect_handle_t handle,
1262 effect_param_t *param)
1263{
1264 uint32_t size = sizeof(int);
1265 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1266 param->vsize;
1267
1268 int status = (*handle)->command(handle,
1269 EFFECT_CMD_SET_PARAM,
1270 sizeof (effect_param_t) + psize,
1271 param,
1272 &size,
1273 &param->status);
1274 if (status == 0)
1275 status = param->status;
1276
1277 return status;
1278}
1279
1280static int set_preprocessor_echo_delay(effect_handle_t handle,
1281 int32_t delay_us)
1282{
1283 struct {
1284 effect_param_t param;
1285 uint32_t data_0;
1286 int32_t data_1;
1287 } buf;
1288 memset(&buf, 0, sizeof(buf));
1289
1290 buf.param.psize = sizeof(uint32_t);
1291 buf.param.vsize = sizeof(uint32_t);
1292 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1293 buf.data_1 = delay_us;
1294
1295 return set_preprocessor_param(handle, &buf.param);
1296}
1297
1298static void push_echo_reference(struct stream_in *in, size_t frames)
1299{
1300 ALOGVV("%s: enter:)", __func__);
1301 /* read frames from echo reference buffer and update echo delay
1302 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1303
1304 int32_t delay_us = update_echo_reference(in, frames)/1000;
1305 int32_t size_in_bytes = 0;
1306 int i;
1307 audio_buffer_t buf;
1308
1309 if (in->ref_buf_frames < frames)
1310 frames = in->ref_buf_frames;
1311
1312 buf.frameCount = frames;
1313 buf.raw = in->ref_buf;
1314
1315 for (i = 0; i < in->num_preprocessors; i++) {
1316 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1317 continue;
1318 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1319 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1320 &buf,
1321 NULL);
1322 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1323 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1324 }
1325
1326 in->ref_buf_frames -= buf.frameCount;
1327 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1328 __func__, in->ref_buf_frames, in->config.channels);
1329 if (in->ref_buf_frames) {
1330 memcpy(in->ref_buf,
1331 in->ref_buf + buf.frameCount * in->config.channels,
1332 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1333 }
1334}
1335
1336static void put_echo_reference(struct audio_device *adev,
1337 struct echo_reference_itfe *reference)
1338{
1339 ALOGV("%s: enter:)", __func__);
1340 int32_t prev_generation = adev->echo_reference_generation;
1341 struct stream_out *out = adev->primary_output;
1342
1343 if (adev->echo_reference != NULL &&
1344 reference == adev->echo_reference) {
1345 /* echo reference is taken from the low latency output stream used
1346 * for voice use cases */
1347 adev->echo_reference = NULL;
1348 android_atomic_inc(&adev->echo_reference_generation);
1349 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1350 // if the primary output is in standby or did not pick the echo reference yet
1351 // we can safely get rid of it here.
1352 // otherwise, out_write() or out_standby() will detect the change in echo reference
1353 // generation and release the echo reference owned by the stream.
1354 if ((out->echo_reference_generation != prev_generation) || out->standby)
1355 release_echo_reference(reference);
1356 } else {
1357 release_echo_reference(reference);
1358 }
1359 ALOGV("release_echo_reference");
1360 }
1361}
1362
1363static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1364 audio_format_t format __unused,
1365 uint32_t channel_count,
1366 uint32_t sampling_rate)
1367{
1368 ALOGV("%s: enter:)", __func__);
1369 put_echo_reference(adev, adev->echo_reference);
1370 /* echo reference is taken from the low latency output stream used
1371 * for voice use cases */
1372 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1373 !adev->primary_output->standby) {
1374 struct audio_stream *stream =
1375 &adev->primary_output->stream.common;
1376 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1377 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1378 ALOGV("Calling create_echo_reference");
1379 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1380 channel_count,
1381 sampling_rate,
1382 AUDIO_FORMAT_PCM_16_BIT,
1383 wr_channel_count,
1384 wr_sampling_rate,
1385 &adev->echo_reference);
1386 if (status == 0)
1387 android_atomic_inc(&adev->echo_reference_generation);
1388 }
1389 return adev->echo_reference;
1390}
1391
1392#ifdef HW_AEC_LOOPBACK
1393static int get_hw_echo_reference(struct stream_in *in)
1394{
1395 struct pcm_device_profile *ref_pcm_profile;
1396 struct pcm_device *ref_device;
1397 struct audio_device *adev = in->dev;
1398
1399 in->hw_echo_reference = false;
1400
1401 if (adev->primary_output!= NULL &&
1402 !adev->primary_output->standby &&
1403 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1404 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1405 struct audio_stream *stream = &adev->primary_output->stream.common;
1406
1407 // TODO: currently there is no low latency mode for aec reference.
1408 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1409 if (ref_pcm_profile == NULL) {
1410 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1411 __func__, pcm_device_capture_loopback_aec.devices);
1412 return -EINVAL;
1413 }
1414
1415 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01001416 if (ref_device == NULL) {
1417 return -ENOMEM;
1418 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001419 ref_device->pcm_profile = ref_pcm_profile;
1420
1421 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1422 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1423
1424 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1425 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1426 pcm_close(ref_device->pcm);
1427 ref_device->pcm = NULL;
1428 return -EIO;
1429 }
1430 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1431
1432 in->hw_echo_reference = true;
1433
1434 ALOGV("%s: hw_echo_reference is true", __func__);
1435 }
1436
1437 return 0;
1438}
1439#endif
1440
1441static int get_playback_delay(struct stream_out *out,
1442 size_t frames,
1443 struct echo_reference_buffer *buffer)
1444{
1445 unsigned int kernel_frames;
1446 int status;
1447 int primary_pcm = 0;
1448 struct pcm_device *pcm_device;
1449
1450 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1451 struct pcm_device, stream_list_node);
1452
1453 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1454 if (status < 0) {
1455 buffer->time_stamp.tv_sec = 0;
1456 buffer->time_stamp.tv_nsec = 0;
1457 buffer->delay_ns = 0;
1458 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1459 "setting playbackTimestamp to 0");
1460 return status;
1461 }
1462
1463 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1464
1465 /* adjust render time stamp with delay added by current driver buffer.
1466 * Add the duration of current frame as we want the render time of the last
1467 * sample being written. */
1468 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1469 out->config.rate);
1470 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1471 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1472
1473 return 0;
1474}
1475
1476#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1477 do { \
1478 if (fct_status != 0) \
1479 status = fct_status; \
1480 else if (cmd_status != 0) \
1481 status = cmd_status; \
1482 } while(0)
1483
1484static int in_configure_reverse(struct stream_in *in)
1485{
1486 int32_t cmd_status;
1487 uint32_t size = sizeof(int);
1488 effect_config_t config;
1489 int32_t status = 0;
1490 int32_t fct_status = 0;
1491 int i;
1492 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1493 if (in->num_preprocessors > 0) {
1494 config.inputCfg.channels = in->main_channels;
1495 config.outputCfg.channels = in->main_channels;
1496 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1497 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1498 config.inputCfg.samplingRate = in->requested_rate;
1499 config.outputCfg.samplingRate = in->requested_rate;
1500 config.inputCfg.mask =
1501 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1502 config.outputCfg.mask =
1503 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1504
1505 for (i = 0; i < in->num_preprocessors; i++)
1506 {
1507 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1508 continue;
1509 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1510 in->preprocessors[i].effect_itfe,
1511 EFFECT_CMD_SET_CONFIG_REVERSE,
1512 sizeof(effect_config_t),
1513 &config,
1514 &size,
1515 &cmd_status);
1516 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1517 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1518 }
1519 }
1520 return status;
1521}
1522
1523#define MAX_NUM_CHANNEL_CONFIGS 10
1524
1525static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1526 struct effect_info_s *effect_info)
1527{
1528 /* size and format of the cmd are defined in hardware/audio_effect.h */
1529 effect_handle_t effect = effect_info->effect_itfe;
1530 uint32_t cmd_size = 2 * sizeof(uint32_t);
1531 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1532 /* reply = status + number of configs (n) + n x channel_config_t */
1533 uint32_t reply_size =
1534 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1535 int32_t reply[reply_size];
1536 int32_t cmd_status;
1537
1538 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1539 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1540 ALOG_ASSERT((effect_info->channel_configs == NULL),
1541 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1542
1543 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1544 * This error will be interpreted as if the effect supports the main_channels but does not
1545 * support any aux_channels */
1546 cmd_status = (*effect)->command(effect,
1547 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1548 cmd_size,
1549 (void*)&cmd,
1550 &reply_size,
1551 (void*)&reply);
1552
1553 if (cmd_status != 0) {
1554 ALOGV("in_read_audio_effect_channel_configs(): "
1555 "fx->command returned %d", cmd_status);
1556 return;
1557 }
1558
1559 if (reply[0] != 0) {
1560 ALOGW("in_read_audio_effect_channel_configs(): "
1561 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1562 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1563 return;
1564 }
1565
1566 /* the feature is not supported */
1567 ALOGV("in_read_audio_effect_channel_configs()(): "
1568 "Feature supported and adding %d channel configs to the list", reply[1]);
1569 effect_info->num_channel_configs = reply[1];
1570 effect_info->channel_configs =
1571 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1572 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1573}
1574
1575
1576#define NUM_IN_AUX_CNL_CONFIGS 2
1577static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1578 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1579 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1580};
1581static uint32_t in_get_aux_channels(struct stream_in *in)
1582{
1583 int i;
1584 channel_config_t new_chcfg = {0, 0};
1585
1586 if (in->num_preprocessors == 0)
1587 return 0;
1588
1589 /* do not enable dual mic configurations when capturing from other microphones than
1590 * main or sub */
1591 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1592 return 0;
1593
1594 /* retain most complex aux channels configuration compatible with requested main channels and
1595 * supported by audio driver and all pre processors */
1596 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1597 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1598 if (cur_chcfg->main_channels == in->main_channels) {
1599 size_t match_cnt;
1600 size_t idx_preproc;
1601 for (idx_preproc = 0, match_cnt = 0;
1602 /* no need to continue if at least one preprocessor doesn't match */
1603 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1604 idx_preproc++) {
1605 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1606 size_t idx_chcfg;
1607
1608 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1609 if (memcmp(effect_info->channel_configs + idx_chcfg,
1610 cur_chcfg,
1611 sizeof(channel_config_t)) == 0) {
1612 match_cnt++;
1613 break;
1614 }
1615 }
1616 }
1617 /* if all preprocessors match, we have a candidate */
1618 if (match_cnt == (size_t)in->num_preprocessors) {
1619 /* retain most complex aux channels configuration */
1620 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1621 new_chcfg = *cur_chcfg;
1622 }
1623 }
1624 }
1625 }
1626
1627 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1628
1629 return new_chcfg.aux_channels;
1630}
1631
1632static int in_configure_effect_channels(effect_handle_t effect,
1633 channel_config_t *channel_config)
1634{
1635 int status = 0;
1636 int fct_status;
1637 int32_t cmd_status;
1638 uint32_t reply_size;
1639 effect_config_t config;
1640 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1641
1642 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1643 channel_config->main_channels,
1644 channel_config->aux_channels);
1645
1646 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1647 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1648 reply_size = sizeof(effect_config_t);
1649 fct_status = (*effect)->command(effect,
1650 EFFECT_CMD_GET_CONFIG,
1651 0,
1652 NULL,
1653 &reply_size,
1654 &config);
1655 if (fct_status != 0) {
1656 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1657 return fct_status;
1658 }
1659
1660 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1661 config.outputCfg.channels = config.inputCfg.channels;
1662 reply_size = sizeof(uint32_t);
1663 fct_status = (*effect)->command(effect,
1664 EFFECT_CMD_SET_CONFIG,
1665 sizeof(effect_config_t),
1666 &config,
1667 &reply_size,
1668 &cmd_status);
1669 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1670
1671 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1672 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1673 reply_size = sizeof(uint32_t);
1674 fct_status = (*effect)->command(effect,
1675 EFFECT_CMD_SET_FEATURE_CONFIG,
1676 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1677 cmd,
1678 &reply_size,
1679 &cmd_status);
1680 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1681
1682 /* some implementations need to be re-enabled after a config change */
1683 reply_size = sizeof(uint32_t);
1684 fct_status = (*effect)->command(effect,
1685 EFFECT_CMD_ENABLE,
1686 0,
1687 NULL,
1688 &reply_size,
1689 &cmd_status);
1690 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1691
1692 return status;
1693}
1694
1695static int in_reconfigure_channels(struct stream_in *in,
1696 effect_handle_t effect,
1697 channel_config_t *channel_config,
1698 bool config_changed) {
1699
1700 int status = 0;
1701
1702 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1703 config_changed, effect);
1704
1705 /* if config changed, reconfigure all previously added effects */
1706 if (config_changed) {
1707 int i;
1708 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1709 for (i = 0; i < in->num_preprocessors; i++)
1710 {
1711 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1712 channel_config);
1713 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1714 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1715 if (cur_status != 0) {
1716 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1717 "%d with channels: [%04x][%04x]",
1718 cur_status,
1719 i,
1720 channel_config->main_channels,
1721 channel_config->aux_channels);
1722 status = cur_status;
1723 }
1724 }
1725 } else if (effect != NULL && channel_config->aux_channels) {
1726 /* if aux channels config did not change but aux channels are present,
1727 * we still need to configure the effect being added */
1728 status = in_configure_effect_channels(effect, channel_config);
1729 }
1730 return status;
1731}
1732
1733static void in_update_aux_channels(struct stream_in *in,
1734 effect_handle_t effect)
1735{
1736 uint32_t aux_channels;
1737 channel_config_t channel_config;
1738 int status;
1739
1740 aux_channels = in_get_aux_channels(in);
1741
1742 channel_config.main_channels = in->main_channels;
1743 channel_config.aux_channels = aux_channels;
1744 status = in_reconfigure_channels(in,
1745 effect,
1746 &channel_config,
1747 (aux_channels != in->aux_channels));
1748
1749 if (status != 0) {
1750 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1751 /* resetting aux channels configuration */
1752 aux_channels = 0;
1753 channel_config.aux_channels = 0;
1754 in_reconfigure_channels(in, effect, &channel_config, true);
1755 }
1756 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1757 if (in->aux_channels != aux_channels) {
1758 in->aux_channels_changed = true;
1759 in->aux_channels = aux_channels;
1760 do_in_standby_l(in);
1761 }
1762}
1763#endif
1764
1765/* This function reads PCM data and:
1766 * - resample if needed
1767 * - process if pre-processors are attached
1768 * - discard unwanted channels
1769 */
1770static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1771{
1772 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001773 size_t src_channels = in->config.channels;
1774 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1775 int i;
1776 void *proc_buf_out;
1777 struct pcm_device *pcm_device;
1778 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1779#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001780 audio_buffer_t in_buf;
1781 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001782 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1783#endif
1784
1785 /* Additional channels might be added on top of main_channels:
1786 * - aux_channels (by processing effects)
1787 * - extra channels due to HW limitations
1788 * In case of additional channels, we cannot work inplace
1789 */
1790 if (has_additional_channels)
1791 proc_buf_out = in->proc_buf_out;
1792 else
1793 proc_buf_out = buffer;
1794
1795 if (list_empty(&in->pcm_dev_list)) {
1796 ALOGE("%s: pcm device list empty", __func__);
1797 return -EINVAL;
1798 }
1799
1800 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1801 struct pcm_device, stream_list_node);
1802
1803#ifdef PREPROCESSING_ENABLED
1804 if (has_processing) {
1805 /* since all the processing below is done in frames and using the config.channels
1806 * as the number of channels, no changes is required in case aux_channels are present */
1807 while (frames_wr < frames) {
1808 /* first reload enough frames at the end of process input buffer */
1809 if (in->proc_buf_frames < (size_t)frames) {
1810 ssize_t frames_rd;
1811 if (in->proc_buf_size < (size_t)frames) {
1812 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1813 in->proc_buf_size = (size_t)frames;
1814 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1815 ALOG_ASSERT((in->proc_buf_in != NULL),
1816 "process_frames() failed to reallocate proc_buf_in");
1817 if (has_additional_channels) {
1818 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1819 ALOG_ASSERT((in->proc_buf_out != NULL),
1820 "process_frames() failed to reallocate proc_buf_out");
1821 proc_buf_out = in->proc_buf_out;
1822 }
1823 }
1824 frames_rd = read_frames(in,
1825 in->proc_buf_in +
1826 in->proc_buf_frames * in->config.channels,
1827 frames - in->proc_buf_frames);
1828 if (frames_rd < 0) {
1829 /* Return error code */
1830 frames_wr = frames_rd;
1831 break;
1832 }
1833 in->proc_buf_frames += frames_rd;
1834 }
1835
1836 if (in->echo_reference != NULL) {
1837 push_echo_reference(in, in->proc_buf_frames);
1838 }
1839
1840 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1841 * the maximum number of frames to be consumed and produced by process() */
1842 in_buf.frameCount = in->proc_buf_frames;
1843 in_buf.s16 = in->proc_buf_in;
1844 out_buf.frameCount = frames - frames_wr;
1845 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1846
1847 /* FIXME: this works because of current pre processing library implementation that
1848 * does the actual process only when the last enabled effect process is called.
1849 * The generic solution is to have an output buffer for each effect and pass it as
1850 * input to the next.
1851 */
1852 for (i = 0; i < in->num_preprocessors; i++) {
1853 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1854 &in_buf,
1855 &out_buf);
1856 }
1857
1858 /* process() has updated the number of frames consumed and produced in
1859 * in_buf.frameCount and out_buf.frameCount respectively
1860 * move remaining frames to the beginning of in->proc_buf_in */
1861 in->proc_buf_frames -= in_buf.frameCount;
1862
1863 if (in->proc_buf_frames) {
1864 memcpy(in->proc_buf_in,
1865 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1866 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1867 }
1868
1869 /* if not enough frames were passed to process(), read more and retry. */
1870 if (out_buf.frameCount == 0) {
1871 ALOGW("No frames produced by preproc");
1872 continue;
1873 }
1874
1875 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1876 frames_wr += out_buf.frameCount;
1877 } else {
1878 /* The effect does not comply to the API. In theory, we should never end up here! */
1879 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1880 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1881 frames_wr = frames;
1882 }
1883 }
1884 }
1885 else
1886#endif //PREPROCESSING_ENABLED
1887 {
1888 /* No processing effects attached */
1889 if (has_additional_channels) {
1890 /* With additional channels, we cannot use original buffer */
1891 if (in->proc_buf_size < (size_t)frames) {
1892 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1893 in->proc_buf_size = (size_t)frames;
1894 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1895 ALOG_ASSERT((in->proc_buf_out != NULL),
1896 "process_frames() failed to reallocate proc_buf_out");
1897 proc_buf_out = in->proc_buf_out;
1898 }
1899 }
1900 frames_wr = read_frames(in, proc_buf_out, frames);
1901 }
1902
1903 /* Remove all additional channels that have been added on top of main_channels:
1904 * - aux_channels
1905 * - extra channels from HW due to HW limitations
1906 * Assumption is made that the channels are interleaved and that the main
1907 * channels are first. */
1908
1909 if (has_additional_channels)
1910 {
1911 int16_t* src_buffer = (int16_t *)proc_buf_out;
1912 int16_t* dst_buffer = (int16_t *)buffer;
1913
1914 if (dst_channels == 1) {
1915 for (i = frames_wr; i > 0; i--)
1916 {
1917 *dst_buffer++ = *src_buffer;
1918 src_buffer += src_channels;
1919 }
1920 } else {
1921 for (i = frames_wr; i > 0; i--)
1922 {
1923 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1924 dst_buffer += dst_channels;
1925 src_buffer += src_channels;
1926 }
1927 }
1928 }
1929
1930 return frames_wr;
1931}
1932
1933static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1934 struct resampler_buffer* buffer)
1935{
1936 struct stream_in *in;
1937 struct pcm_device *pcm_device;
1938
1939 if (buffer_provider == NULL || buffer == NULL)
1940 return -EINVAL;
1941
1942 in = (struct stream_in *)((char *)buffer_provider -
1943 offsetof(struct stream_in, buf_provider));
1944
1945 if (list_empty(&in->pcm_dev_list)) {
1946 buffer->raw = NULL;
1947 buffer->frame_count = 0;
1948 in->read_status = -ENODEV;
1949 return -ENODEV;
1950 }
1951
1952 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1953 struct pcm_device, stream_list_node);
1954
1955 if (in->read_buf_frames == 0) {
1956 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1957 if (in->read_buf_size < in->config.period_size) {
1958 in->read_buf_size = in->config.period_size;
1959 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1960 ALOG_ASSERT((in->read_buf != NULL),
1961 "get_next_buffer() failed to reallocate read_buf");
1962 }
1963
1964 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1965
1966 if (in->read_status != 0) {
1967 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1968 buffer->raw = NULL;
1969 buffer->frame_count = 0;
1970 return in->read_status;
1971 }
1972 in->read_buf_frames = in->config.period_size;
1973
1974#ifdef PREPROCESSING_ENABLED
1975#ifdef HW_AEC_LOOPBACK
1976 if (in->hw_echo_reference) {
1977 struct pcm_device *temp_device = NULL;
1978 struct pcm_device *ref_device = NULL;
1979 struct listnode *node = NULL;
1980 struct echo_reference_buffer b;
1981 size_t size_hw_ref_bytes;
1982 size_t size_hw_ref_frames;
1983 int read_status = 0;
1984
1985 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1986 struct pcm_device, stream_list_node);
1987 list_for_each(node, &in->pcm_dev_list) {
1988 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
1989 if (temp_device->pcm_profile->id == 1) {
1990 ref_device = temp_device;
1991 break;
1992 }
1993 }
1994 if (ref_device) {
1995 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
1996 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
1997 if (in->hw_ref_buf_size < size_hw_ref_frames) {
1998 in->hw_ref_buf_size = size_hw_ref_frames;
1999 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
2000 ALOG_ASSERT((in->hw_ref_buf != NULL),
2001 "get_next_buffer() failed to reallocate hw_ref_buf");
2002 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
2003 in->hw_ref_buf, size_hw_ref_bytes);
2004 }
2005
2006 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
2007 if (read_status != 0) {
2008 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
2009 b.raw = NULL;
2010 b.frame_count = 0;
2011 }
2012 else {
2013 get_capture_reference_delay(in, size_hw_ref_frames, &b);
2014 b.raw = (void *)in->hw_ref_buf;
2015 b.frame_count = size_hw_ref_frames;
2016 if (b.delay_ns != 0)
2017 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
2018 in->echo_reference->write(in->echo_reference, &b);
2019 }
2020 }
2021 }
2022#endif // HW_AEC_LOOPBACK
2023#endif // PREPROCESSING_ENABLED
2024 }
2025
2026 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
2027 in->read_buf_frames : buffer->frame_count;
2028 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
2029 in->config.channels;
2030 return in->read_status;
2031}
2032
2033static void release_buffer(struct resampler_buffer_provider *buffer_provider,
2034 struct resampler_buffer* buffer)
2035{
2036 struct stream_in *in;
2037
2038 if (buffer_provider == NULL || buffer == NULL)
2039 return;
2040
2041 in = (struct stream_in *)((char *)buffer_provider -
2042 offsetof(struct stream_in, buf_provider));
2043
2044 in->read_buf_frames -= buffer->frame_count;
2045}
2046
2047/* read_frames() reads frames from kernel driver, down samples to capture rate
2048 * if necessary and output the number of frames requested to the buffer specified */
2049static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
2050{
2051 ssize_t frames_wr = 0;
2052
2053 struct pcm_device *pcm_device;
2054
2055 if (list_empty(&in->pcm_dev_list)) {
2056 ALOGE("%s: pcm device list empty", __func__);
2057 return -EINVAL;
2058 }
2059
2060 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2061 struct pcm_device, stream_list_node);
2062
2063 while (frames_wr < frames) {
2064 size_t frames_rd = frames - frames_wr;
2065 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2066 __func__,frames_rd,frames_wr,in->config.channels);
2067 if (in->resampler != NULL) {
2068 in->resampler->resample_from_provider(in->resampler,
2069 (int16_t *)((char *)buffer +
2070 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2071 &frames_rd);
2072 } else {
2073 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002074 .raw = NULL,
2075 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002076 };
2077 get_next_buffer(&in->buf_provider, &buf);
2078 if (buf.raw != NULL) {
2079 memcpy((char *)buffer +
2080 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2081 buf.raw,
2082 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2083 frames_rd = buf.frame_count;
2084 }
2085 release_buffer(&in->buf_provider, &buf);
2086 }
2087 /* in->read_status is updated by getNextBuffer() also called by
2088 * in->resampler->resample_from_provider() */
2089 if (in->read_status != 0)
2090 return in->read_status;
2091
2092 frames_wr += frames_rd;
2093 }
2094 return frames_wr;
2095}
2096
2097static int in_release_pcm_devices(struct stream_in *in)
2098{
2099 struct pcm_device *pcm_device;
2100 struct listnode *node;
2101 struct listnode *next;
2102
2103 list_for_each_safe(node, next, &in->pcm_dev_list) {
2104 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2105 list_remove(node);
2106 free(pcm_device);
2107 }
2108
2109 return 0;
2110}
2111
2112static int stop_input_stream(struct stream_in *in)
2113{
2114 struct audio_usecase *uc_info;
2115 struct audio_device *adev = in->dev;
2116
2117 adev->active_input = NULL;
2118 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2119 in->usecase, use_case_table[in->usecase]);
2120 uc_info = get_usecase_from_id(adev, in->usecase);
2121 if (uc_info == NULL) {
2122 ALOGE("%s: Could not find the usecase (%d) in the list",
2123 __func__, in->usecase);
2124 return -EINVAL;
2125 }
2126
2127 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002128 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002129
2130 list_remove(&uc_info->adev_list_node);
2131 free(uc_info);
2132
2133 if (list_empty(&in->pcm_dev_list)) {
2134 ALOGE("%s: pcm device list empty", __func__);
2135 return -EINVAL;
2136 }
2137
2138 in_release_pcm_devices(in);
2139 list_init(&in->pcm_dev_list);
2140
2141#ifdef HW_AEC_LOOPBACK
2142 if (in->hw_echo_reference)
2143 {
2144 in->hw_echo_reference = false;
2145 }
2146#endif
2147
2148 ALOGV("%s: exit", __func__);
2149 return 0;
2150}
2151
2152static int start_input_stream(struct stream_in *in)
2153{
2154 /* Enable output device and stream routing controls */
2155 int ret = 0;
2156 bool recreate_resampler = false;
2157 struct audio_usecase *uc_info;
2158 struct audio_device *adev = in->dev;
2159 struct pcm_device_profile *pcm_profile;
2160 struct pcm_device *pcm_device;
2161
2162 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2163 adev->active_input = in;
2164 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2165 if (pcm_profile == NULL) {
2166 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2167 __func__, in->usecase);
2168 ret = -EINVAL;
2169 goto error_config;
2170 }
2171
2172 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002173 if (uc_info == NULL) {
2174 ret = -ENOMEM;
2175 goto error_config;
2176 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002177 uc_info->id = in->usecase;
2178 uc_info->type = PCM_CAPTURE;
2179 uc_info->stream = (struct audio_stream *)in;
2180 uc_info->devices = in->devices;
2181 uc_info->in_snd_device = SND_DEVICE_NONE;
2182 uc_info->out_snd_device = SND_DEVICE_NONE;
2183
2184 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002185 if (pcm_device == NULL) {
2186 free(uc_info);
2187 ret = -ENOMEM;
2188 goto error_config;
2189 }
2190
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002191 pcm_device->pcm_profile = pcm_profile;
2192 list_init(&in->pcm_dev_list);
2193 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2194
2195 list_init(&uc_info->mixer_list);
2196 list_add_tail(&uc_info->mixer_list,
2197 &adev_get_mixer_for_card(adev,
2198 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2199
2200 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2201
2202 select_devices(adev, in->usecase);
2203
2204 /* Config should be updated as profile can be changed between different calls
2205 * to this function:
2206 * - Trigger resampler creation
2207 * - Config needs to be updated */
2208 if (in->config.rate != pcm_profile->config.rate) {
2209 recreate_resampler = true;
2210 }
2211 in->config = pcm_profile->config;
2212
2213#ifdef PREPROCESSING_ENABLED
2214 if (in->aux_channels_changed) {
2215 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2216 recreate_resampler = true;
2217 }
2218#endif
2219
2220 if (in->requested_rate != in->config.rate) {
2221 recreate_resampler = true;
2222 }
2223
2224 if (recreate_resampler) {
2225 if (in->resampler) {
2226 release_resampler(in->resampler);
2227 in->resampler = NULL;
2228 }
2229 in->buf_provider.get_next_buffer = get_next_buffer;
2230 in->buf_provider.release_buffer = release_buffer;
2231 ret = create_resampler(in->config.rate,
2232 in->requested_rate,
2233 in->config.channels,
2234 RESAMPLER_QUALITY_DEFAULT,
2235 &in->buf_provider,
2236 &in->resampler);
2237 }
2238
2239#ifdef PREPROCESSING_ENABLED
2240 if (in->enable_aec && in->echo_reference == NULL) {
2241 in->echo_reference = get_echo_reference(adev,
2242 AUDIO_FORMAT_PCM_16_BIT,
2243 audio_channel_count_from_in_mask(in->main_channels),
2244 in->requested_rate
2245 );
2246 }
2247
2248#ifdef HW_AEC_LOOPBACK
2249 if (in->enable_aec) {
2250 ret = get_hw_echo_reference(in);
2251 if (ret!=0)
2252 goto error_open;
2253
2254 /* force ref buffer reallocation */
2255 in->hw_ref_buf_size = 0;
2256 }
2257#endif
2258#endif
2259
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002260 if (in->dev->voice.in_call) {
2261 ALOGV("%s: in_call, not handling PCMs", __func__);
2262 goto skip_pcm_handling;
2263 }
2264
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002265 /* Open the PCM device.
2266 * The HW is limited to support only the default pcm_profile settings.
2267 * As such a change in aux_channels will not have an effect.
2268 */
2269 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2270 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2271 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2272 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2273
stenkinevgeniy44335362018-05-07 18:00:13 +00002274 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002275 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2276
stenkinevgeniy44335362018-05-07 18:00:13 +00002277 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2278 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2279 pcm_close(pcm_device->pcm);
2280 pcm_device->pcm = NULL;
2281 ret = -EIO;
2282 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002283 }
2284
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002285skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002286 /* force read and proc buffer reallocation in case of frame size or
2287 * channel count change */
2288 in->proc_buf_frames = 0;
2289 in->proc_buf_size = 0;
2290 in->read_buf_size = 0;
2291 in->read_buf_frames = 0;
2292
2293 /* if no supported sample rate is available, use the resampler */
2294 if (in->resampler) {
2295 in->resampler->reset(in->resampler);
2296 }
2297
2298 ALOGV("%s: exit", __func__);
2299 return ret;
2300
2301error_open:
2302 if (in->resampler) {
2303 release_resampler(in->resampler);
2304 in->resampler = NULL;
2305 }
2306 stop_input_stream(in);
2307
2308error_config:
2309 ALOGV("%s: exit: status(%d)", __func__, ret);
2310 adev->active_input = NULL;
2311 return ret;
2312}
2313
2314void lock_input_stream(struct stream_in *in)
2315{
2316 pthread_mutex_lock(&in->pre_lock);
2317 pthread_mutex_lock(&in->lock);
2318 pthread_mutex_unlock(&in->pre_lock);
2319}
2320
2321void lock_output_stream(struct stream_out *out)
2322{
2323 pthread_mutex_lock(&out->pre_lock);
2324 pthread_mutex_lock(&out->lock);
2325 pthread_mutex_unlock(&out->pre_lock);
2326}
2327
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002328static int uc_release_pcm_devices(struct audio_usecase *usecase)
2329{
2330 struct stream_out *out = (struct stream_out *)usecase->stream;
2331 struct pcm_device *pcm_device;
2332 struct listnode *node;
2333 struct listnode *next;
2334
2335 list_for_each_safe(node, next, &out->pcm_dev_list) {
2336 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2337 list_remove(node);
2338 free(pcm_device);
2339 }
2340 list_init(&usecase->mixer_list);
2341
2342 return 0;
2343}
2344
2345static int uc_select_pcm_devices(struct audio_usecase *usecase)
2346
2347{
2348 struct stream_out *out = (struct stream_out *)usecase->stream;
2349 struct pcm_device *pcm_device;
2350 struct pcm_device_profile *pcm_profile;
2351 struct mixer_card *mixer_card;
2352 audio_devices_t devices = usecase->devices;
2353
2354 list_init(&usecase->mixer_list);
2355 list_init(&out->pcm_dev_list);
2356
2357 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2358 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002359 if (pcm_device == NULL) {
2360 return -ENOMEM;
2361 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002362 pcm_device->pcm_profile = pcm_profile;
2363 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2364 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2365 if (mixer_card == NULL) {
2366 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2367 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2368 }
2369 devices &= ~pcm_profile->devices;
2370 }
2371
2372 return 0;
2373}
2374
2375static int out_close_pcm_devices(struct stream_out *out)
2376{
2377 struct pcm_device *pcm_device;
2378 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002379
2380 list_for_each(node, &out->pcm_dev_list) {
2381 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002382 if (pcm_device->pcm) {
2383 pcm_close(pcm_device->pcm);
2384 pcm_device->pcm = NULL;
2385 }
2386 if (pcm_device->resampler) {
2387 release_resampler(pcm_device->resampler);
2388 pcm_device->resampler = NULL;
2389 }
2390 if (pcm_device->res_buffer) {
2391 free(pcm_device->res_buffer);
2392 pcm_device->res_buffer = NULL;
2393 }
2394 }
2395
2396 return 0;
2397}
2398
2399static int out_open_pcm_devices(struct stream_out *out)
2400{
2401 struct pcm_device *pcm_device;
2402 struct listnode *node;
2403 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002404 int pcm_device_card;
2405 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002406
2407 list_for_each(node, &out->pcm_dev_list) {
2408 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002409 pcm_device_card = pcm_device->pcm_profile->card;
2410 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002411
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002412 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2413 pcm_device_id = pcm_device_deep_buffer.id;
2414
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002415 if (out->dev->voice.in_call) {
2416 ALOGV("%s: in_call, not opening PCMs", __func__);
2417 return ret;
2418 }
2419
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002420 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2421 __func__, pcm_device_card, pcm_device_id);
2422
2423 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002424 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002425
2426 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2427 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2428 pcm_device->pcm = NULL;
2429 ret = -EIO;
2430 goto error_open;
2431 }
2432 /*
2433 * If the stream rate differs from the PCM rate, we need to
2434 * create a resampler.
2435 */
2436 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2437 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2438 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002439 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002440 out->sample_rate, pcm_device->pcm_profile->config.rate);
2441 ret = create_resampler(out->sample_rate,
2442 pcm_device->pcm_profile->config.rate,
2443 audio_channel_count_from_out_mask(out->channel_mask),
2444 RESAMPLER_QUALITY_DEFAULT,
2445 NULL,
2446 &pcm_device->resampler);
2447 pcm_device->res_byte_count = 0;
2448 pcm_device->res_buffer = NULL;
2449 }
2450 }
2451 return ret;
2452
2453error_open:
2454 out_close_pcm_devices(out);
2455 return ret;
2456}
2457
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002458int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002459{
2460 struct audio_device *adev = out->dev;
2461 struct audio_usecase *uc_info;
2462
2463 uc_info = get_usecase_from_id(adev, out->usecase);
2464 if (uc_info == NULL) {
2465 ALOGE("%s: Could not find the usecase (%d) in the list",
2466 __func__, out->usecase);
2467 return -EINVAL;
2468 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002469 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002470 uc_release_pcm_devices(uc_info);
2471 list_remove(&uc_info->adev_list_node);
2472 free(uc_info);
2473
2474 return 0;
2475}
2476
Andreas Schneider56204f62017-01-31 08:17:32 +01002477int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002478{
2479 struct audio_device *adev = out->dev;
2480 struct audio_usecase *uc_info;
2481
2482 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002483 if (uc_info == NULL) {
2484 return -ENOMEM;
2485 }
2486
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002487 uc_info->id = out->usecase;
2488 uc_info->type = PCM_PLAYBACK;
2489 uc_info->stream = (struct audio_stream *)out;
2490 uc_info->devices = out->devices;
2491 uc_info->in_snd_device = SND_DEVICE_NONE;
2492 uc_info->out_snd_device = SND_DEVICE_NONE;
2493 uc_select_pcm_devices(uc_info);
2494
2495 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2496 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002497
2498 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002499}
2500
2501static int stop_output_stream(struct stream_out *out)
2502{
2503 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002504 bool do_disable = true;
2505
2506 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2507 out->usecase, use_case_table[out->usecase]);
2508
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002509 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002510
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002511 if (do_disable)
2512 ret = disable_output_path_l(out);
2513
2514 ALOGV("%s: exit: status(%d)", __func__, ret);
2515 return ret;
2516}
2517
2518static int start_output_stream(struct stream_out *out)
2519{
2520 int ret = 0;
2521 struct audio_device *adev = out->dev;
2522
2523 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2524 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2525
Andreas Schneider56204f62017-01-31 08:17:32 +01002526 ret = enable_output_path_l(out);
2527 if (ret != 0) {
2528 goto error_config;
2529 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002530
2531 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2532 out->compr = NULL;
2533 ret = out_open_pcm_devices(out);
2534 if (ret != 0)
2535 goto error_open;
2536#ifdef PREPROCESSING_ENABLED
2537 out->echo_reference = NULL;
2538 out->echo_reference_generation = adev->echo_reference_generation;
2539 if (adev->echo_reference != NULL)
2540 out->echo_reference = adev->echo_reference;
2541#endif
2542 } else {
2543 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2544 COMPRESS_IN, &out->compr_config);
2545 if (out->compr && !is_compress_ready(out->compr)) {
2546 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2547 compress_close(out->compr);
2548 out->compr = NULL;
2549 ret = -EIO;
2550 goto error_open;
2551 }
2552 if (out->offload_callback)
2553 compress_nonblock(out->compr, out->non_blocking);
2554
2555 if (adev->offload_fx_start_output != NULL)
2556 adev->offload_fx_start_output(out->handle);
2557 }
2558 ALOGV("%s: exit", __func__);
2559 return 0;
2560error_open:
2561 stop_output_stream(out);
2562error_config:
2563 return ret;
2564}
2565
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002566int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002567{
2568 struct audio_usecase *uc_info;
2569
2570 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002571 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002572
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002573 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002574
2575 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2576 if (uc_info == NULL) {
2577 ALOGE("%s: Could not find the usecase (%d) in the list",
2578 __func__, USECASE_VOICE_CALL);
2579 return -EINVAL;
2580 }
2581
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002582 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2583 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002584
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002585 list_remove(&uc_info->adev_list_node);
2586 free(uc_info);
2587
2588 ALOGV("%s: exit", __func__);
2589 return 0;
2590}
2591
2592/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002593int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002594{
2595 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002596 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002597
2598 ALOGV("%s: enter", __func__);
2599
2600 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002601 if (uc_info == NULL) {
2602 ret = -ENOMEM;
2603 goto exit;
2604 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002605 /*
2606 * We set this early so that functions called after this is being set
2607 * can use it. It is e.g. needed in select_devices() to inform the RILD
2608 * which output device we use.
2609 */
2610 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002611
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002612 uc_info->id = USECASE_VOICE_CALL;
2613 uc_info->type = VOICE_CALL;
2614 uc_info->stream = (struct audio_stream *)adev->primary_output;
2615 uc_info->devices = adev->primary_output->devices;
2616 uc_info->in_snd_device = SND_DEVICE_NONE;
2617 uc_info->out_snd_device = SND_DEVICE_NONE;
2618
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002619 list_init(&uc_info->mixer_list);
2620 list_add_tail(&uc_info->mixer_list,
2621 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002622
2623 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2624
2625 select_devices(adev, USECASE_VOICE_CALL);
2626
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002627 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002628
2629 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002630 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002631
Andreas Schneider56204f62017-01-31 08:17:32 +01002632exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002633 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002634 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002635}
2636
2637static int check_input_parameters(uint32_t sample_rate,
2638 audio_format_t format,
2639 int channel_count)
2640{
2641 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2642
2643 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2644
2645 switch (sample_rate) {
2646 case 8000:
2647 case 11025:
2648 case 12000:
2649 case 16000:
2650 case 22050:
2651 case 24000:
2652 case 32000:
2653 case 44100:
2654 case 48000:
2655 break;
2656 default:
2657 return -EINVAL;
2658 }
2659
2660 return 0;
2661}
2662
2663static size_t get_input_buffer_size(uint32_t sample_rate,
2664 audio_format_t format,
2665 int channel_count,
2666 usecase_type_t usecase_type,
2667 audio_devices_t devices)
2668{
2669 size_t size = 0;
2670 struct pcm_device_profile *pcm_profile;
2671
2672 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2673 return 0;
2674
2675 pcm_profile = get_pcm_device(usecase_type, devices);
2676 if (pcm_profile == NULL)
2677 return 0;
2678
2679 /*
2680 * take resampling into account and return the closest majoring
2681 * multiple of 16 frames, as audioflinger expects audio buffers to
2682 * be a multiple of 16 frames
2683 */
2684 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2685 size = ((size + 15) / 16) * 16;
2686
2687 return (size * channel_count * audio_bytes_per_sample(format));
2688
2689}
2690
2691static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2692{
2693 struct stream_out *out = (struct stream_out *)stream;
2694
2695 return out->sample_rate;
2696}
2697
2698static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2699{
2700 (void)stream;
2701 (void)rate;
2702 return -ENOSYS;
2703}
2704
2705static size_t out_get_buffer_size(const struct audio_stream *stream)
2706{
2707 struct stream_out *out = (struct stream_out *)stream;
2708
2709 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2710 return out->compr_config.fragment_size;
2711 }
2712
2713 return out->config.period_size *
2714 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2715}
2716
2717static uint32_t out_get_channels(const struct audio_stream *stream)
2718{
2719 struct stream_out *out = (struct stream_out *)stream;
2720
2721 return out->channel_mask;
2722}
2723
2724static audio_format_t out_get_format(const struct audio_stream *stream)
2725{
2726 struct stream_out *out = (struct stream_out *)stream;
2727
2728 return out->format;
2729}
2730
2731static int out_set_format(struct audio_stream *stream, audio_format_t format)
2732{
2733 (void)stream;
2734 (void)format;
2735 return -ENOSYS;
2736}
2737
2738static int do_out_standby_l(struct stream_out *out)
2739{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002740 int status = 0;
2741
2742 out->standby = true;
2743 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2744 out_close_pcm_devices(out);
2745#ifdef PREPROCESSING_ENABLED
2746 /* stop writing to echo reference */
2747 if (out->echo_reference != NULL) {
2748 out->echo_reference->write(out->echo_reference, NULL);
2749 if (out->echo_reference_generation != adev->echo_reference_generation) {
2750 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2751 release_echo_reference(out->echo_reference);
2752 out->echo_reference_generation = adev->echo_reference_generation;
2753 }
2754 out->echo_reference = NULL;
2755 }
2756#endif
2757 } else {
2758 stop_compressed_output_l(out);
2759 out->gapless_mdata.encoder_delay = 0;
2760 out->gapless_mdata.encoder_padding = 0;
2761 if (out->compr != NULL) {
2762 compress_close(out->compr);
2763 out->compr = NULL;
2764 }
2765 }
2766 status = stop_output_stream(out);
2767
2768 return status;
2769}
2770
2771static int out_standby(struct audio_stream *stream)
2772{
2773 struct stream_out *out = (struct stream_out *)stream;
2774 struct audio_device *adev = out->dev;
2775
2776 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2777 out->usecase, use_case_table[out->usecase]);
2778 lock_output_stream(out);
2779 if (!out->standby) {
2780 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002781 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002782 do_out_standby_l(out);
2783 pthread_mutex_unlock(&adev->lock);
2784 }
2785 pthread_mutex_unlock(&out->lock);
2786 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002787
2788 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2789
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002790 return 0;
2791}
2792
2793static int out_dump(const struct audio_stream *stream, int fd)
2794{
2795 (void)stream;
2796 (void)fd;
2797
2798 return 0;
2799}
2800
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002801static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2802{
2803 struct stream_out *out = (struct stream_out *)stream;
2804 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002805 struct listnode *node;
2806 struct str_parms *parms;
2807 char value[32];
2808 int ret, val = 0;
2809 struct audio_usecase *uc_info;
2810 bool do_standby = false;
2811 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002812#ifdef PREPROCESSING_ENABLED
2813 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2814#endif
2815
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002816 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2817 "adev->mode(%#x)",
2818 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2819 out->devices, adev->mode);
2820
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002821 parms = str_parms_create_str(kvpairs);
2822 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2823 if (ret >= 0) {
2824 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002825
2826 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2827 __func__, out->usecase, use_case_table[out->usecase], val,
2828 adev->mode);
2829
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002830 pthread_mutex_lock(&adev->lock_inputs);
2831 lock_output_stream(out);
2832 pthread_mutex_lock(&adev->lock);
2833#ifdef PREPROCESSING_ENABLED
2834 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2835 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2836 /* reset active input:
2837 * - to attach the echo reference
2838 * - because a change in output device may change mic settings */
2839 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2840 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2841 in = adev->active_input;
2842 }
2843 }
2844#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002845 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002846 bool bt_sco_active = false;
2847
2848 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2849 bt_sco_active = true;
2850 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002851 out->devices = val;
2852
2853 if (!out->standby) {
2854 uc_info = get_usecase_from_id(adev, out->usecase);
2855 if (uc_info == NULL) {
2856 ALOGE("%s: Could not find the usecase (%d) in the list",
2857 __func__, out->usecase);
2858 } else {
2859 list_for_each(node, &out->pcm_dev_list) {
2860 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2861 if ((pcm_device->pcm_profile->devices & val) == 0)
2862 do_standby = true;
2863 val &= ~pcm_device->pcm_profile->devices;
2864 }
2865 if (val != 0)
2866 do_standby = true;
2867 }
2868 if (do_standby)
2869 do_out_standby_l(out);
2870 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002871 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2872 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002873 select_devices(adev, out->usecase);
2874 }
2875 }
2876
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002877 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002878 (out == adev->primary_output)) {
2879 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002880 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2881 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002882 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002883 /* Turn on bluetooth if needed */
2884 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002885 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002886 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002887 } else {
2888 /*
2889 * When we select different devices we need to restart the
2890 * voice call. The modem closes the stream on its end and
2891 * we do not get any output.
2892 */
2893 stop_voice_call(adev);
2894 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002895 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002896 }
2897 }
2898
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002899 pthread_mutex_unlock(&adev->lock);
2900 pthread_mutex_unlock(&out->lock);
2901#ifdef PREPROCESSING_ENABLED
2902 if (in) {
2903 /* The lock on adev->lock_inputs prevents input stream from being closed */
2904 lock_input_stream(in);
2905 pthread_mutex_lock(&adev->lock);
2906 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2907 do_in_standby_l(in);
2908 pthread_mutex_unlock(&adev->lock);
2909 pthread_mutex_unlock(&in->lock);
2910 }
2911#endif
2912 pthread_mutex_unlock(&adev->lock_inputs);
2913 }
2914
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002915 amplifier_set_parameters(parms);
2916
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002917 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2918 parse_compress_metadata(out, parms);
2919 }
2920
2921 str_parms_destroy(parms);
2922
2923 if (ret > 0)
2924 ret = 0;
2925 ALOGV("%s: exit: code(%d)", __func__, ret);
2926 return ret;
2927}
2928
2929static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2930{
2931 struct stream_out *out = (struct stream_out *)stream;
2932 struct str_parms *query = str_parms_create_str(keys);
2933 char *str;
2934 char value[256];
2935 struct str_parms *reply = str_parms_create();
2936 size_t i, j;
2937 int ret;
2938 bool first = true;
2939 ALOGV("%s: enter: keys - %s", __func__, keys);
2940 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2941 if (ret >= 0) {
2942 value[0] = '\0';
2943 i = 0;
2944 while (out->supported_channel_masks[i] != 0) {
2945 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2946 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2947 if (!first) {
2948 strcat(value, "|");
2949 }
2950 strcat(value, out_channels_name_to_enum_table[j].name);
2951 first = false;
2952 break;
2953 }
2954 }
2955 i++;
2956 }
2957 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2958 str = str_parms_to_str(reply);
2959 } else {
2960 str = strdup(keys);
2961 }
2962 str_parms_destroy(query);
2963 str_parms_destroy(reply);
2964 ALOGV("%s: exit: returns - %s", __func__, str);
2965 return str;
2966}
2967
2968static uint32_t out_get_latency(const struct audio_stream_out *stream)
2969{
2970 struct stream_out *out = (struct stream_out *)stream;
2971
2972 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2973 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2974
2975 return (out->config.period_count * out->config.period_size * 1000) /
2976 (out->config.rate);
2977}
2978
2979static int out_set_volume(struct audio_stream_out *stream, float left,
2980 float right)
2981{
2982 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002983
2984 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2985 /* only take left channel into account: the API is for stereo anyway */
2986 out->muted = (left == 0.0f);
2987 return 0;
2988 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002989 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002990 }
2991
2992 return -ENOSYS;
2993}
2994
Andreas Schneider3b643832017-01-31 11:48:22 +01002995#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002996static int fast_set_affinity(pid_t tid) {
2997 cpu_set_t cpu_set;
2998 int cpu_num;
2999 const char *irq_procfs = "/proc/asound/irq_affinity";
3000 FILE *fp;
3001
3002 if ((fp = fopen(irq_procfs, "r")) == NULL) {
3003 ALOGW("Procfs node %s not found", irq_procfs);
3004 return -1;
3005 }
3006
3007 if (fscanf(fp, "%d", &cpu_num) != 1) {
3008 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
3009 fclose(fp);
3010 return -1;
3011 }
3012 fclose(fp);
3013
3014 CPU_ZERO(&cpu_set);
3015 CPU_SET(cpu_num, &cpu_set);
3016 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
3017}
Andreas Schneider3b643832017-01-31 11:48:22 +01003018#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003019
3020static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
3021 size_t bytes)
3022{
3023 struct stream_out *out = (struct stream_out *)stream;
3024 struct audio_device *adev = out->dev;
3025 ssize_t ret = 0;
3026 struct pcm_device *pcm_device;
3027 struct listnode *node;
3028 size_t frame_size = audio_stream_out_frame_size(stream);
3029 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003030#ifdef PREPROCESSING_ENABLED
3031 size_t in_frames = bytes / frame_size;
3032 size_t out_frames = in_frames;
3033 struct stream_in *in = NULL;
3034#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003035
3036 lock_output_stream(out);
3037
Andreas Schneider3b643832017-01-31 11:48:22 +01003038#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003039 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003040 pid_t tid = gettid();
3041 int err;
3042
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003043 err = fast_set_affinity(tid);
3044 if (err < 0) {
3045 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3046 }
3047 out->is_fastmixer_affinity_set = true;
3048 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003049#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003050
3051 if (out->standby) {
3052#ifdef PREPROCESSING_ENABLED
3053 pthread_mutex_unlock(&out->lock);
3054 /* Prevent input stream from being closed */
3055 pthread_mutex_lock(&adev->lock_inputs);
3056 lock_output_stream(out);
3057 if (!out->standby) {
3058 pthread_mutex_unlock(&adev->lock_inputs);
3059 goto false_alarm;
3060 }
3061#endif
3062 pthread_mutex_lock(&adev->lock);
3063 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003064 if (ret == 0) {
3065 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
3066 }
3067
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003068 /* ToDo: If use case is compress offload should return 0 */
3069 if (ret != 0) {
3070 pthread_mutex_unlock(&adev->lock);
3071#ifdef PREPROCESSING_ENABLED
3072 pthread_mutex_unlock(&adev->lock_inputs);
3073#endif
3074 goto exit;
3075 }
3076 out->standby = false;
3077
3078#ifdef PREPROCESSING_ENABLED
3079 /* A change in output device may change the microphone selection */
3080 if (adev->active_input &&
3081 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
3082 adev->active_input->source == AUDIO_SOURCE_MIC)) {
3083 in = adev->active_input;
3084 ALOGV("%s: enter:) force_input_standby true", __func__);
3085 }
3086#endif
3087 pthread_mutex_unlock(&adev->lock);
3088#ifdef PREPROCESSING_ENABLED
3089 if (!in) {
3090 /* Leave mutex locked iff in != NULL */
3091 pthread_mutex_unlock(&adev->lock_inputs);
3092 }
3093#endif
3094 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003095#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003096false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003097#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003098
3099 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003100 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003101 return ret;
3102 } else {
3103#ifdef PREPROCESSING_ENABLED
3104 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3105 != out->echo_reference_generation) {
3106 pthread_mutex_lock(&adev->lock);
3107 if (out->echo_reference != NULL) {
3108 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3109 release_echo_reference(out->echo_reference);
3110 }
3111 // note that adev->echo_reference_generation here can be different from the one
3112 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3113 // with what has been set by get_echo_reference() or put_echo_reference()
3114 out->echo_reference_generation = adev->echo_reference_generation;
3115 out->echo_reference = adev->echo_reference;
3116 ALOGV("%s: update echo reference generation %d", __func__,
3117 out->echo_reference_generation);
3118 pthread_mutex_unlock(&adev->lock);
3119 }
3120#endif
3121
3122 if (out->muted)
3123 memset((void *)buffer, 0, bytes);
3124 list_for_each(node, &out->pcm_dev_list) {
3125 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3126 if (pcm_device->resampler) {
3127 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
3128 > pcm_device->res_byte_count) {
3129 pcm_device->res_byte_count =
3130 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
3131 pcm_device->res_buffer =
3132 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
3133 ALOGV("%s: resampler res_byte_count = %zu", __func__,
3134 pcm_device->res_byte_count);
3135 }
3136 frames_rq = bytes / frame_size;
3137 frames_wr = pcm_device->res_byte_count / frame_size;
3138 ALOGVV("%s: resampler request frames = %d frame_size = %d",
3139 __func__, frames_rq, frame_size);
3140 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3141 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3142 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3143 }
3144 if (pcm_device->pcm) {
3145#ifdef PREPROCESSING_ENABLED
3146 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3147 struct echo_reference_buffer b;
3148 b.raw = (void *)buffer;
3149 b.frame_count = in_frames;
3150
3151 get_playback_delay(out, out_frames, &b);
3152 out->echo_reference->write(out->echo_reference, &b);
3153 }
3154#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003155 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3156 if (pcm_device->resampler && pcm_device->res_buffer)
3157 pcm_device->status =
3158 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3159 frames_wr * frame_size);
3160 else
3161 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3162 if (pcm_device->status != 0)
3163 ret = pcm_device->status;
3164 }
3165 }
3166 if (ret == 0)
3167 out->written += bytes / (out->config.channels * sizeof(short));
3168 }
3169
3170exit:
3171 pthread_mutex_unlock(&out->lock);
3172
3173 if (ret != 0) {
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->pcm && pcm_device->status != 0)
3177 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3178 }
3179 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003180 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3181 clock_gettime(CLOCK_MONOTONIC, &t);
3182 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3183 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3184 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3185 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3186 if (sleep_time > 0) {
3187 usleep(sleep_time);
3188 } else {
3189 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3190 sleep_time = 0;
3191 }
3192 out->last_write_time_us = now + sleep_time;
3193 // last_write_time_us is an approximation of when the (simulated) alsa
3194 // buffer is believed completely full. The usleep above waits for more space
3195 // in the buffer, but by the end of the sleep the buffer is considered
3196 // topped-off.
3197 //
3198 // On the subsequent out_write(), we measure the elapsed time spent in
3199 // the mixer. This is subtracted from the sleep estimate based on frames,
3200 // thereby accounting for drain in the alsa buffer during mixing.
3201 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003202 }
3203
3204#ifdef PREPROCESSING_ENABLED
3205 if (in) {
3206 /* The lock on adev->lock_inputs prevents input stream from being closed */
3207 lock_input_stream(in);
3208 pthread_mutex_lock(&adev->lock);
3209 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3210 do_in_standby_l(in);
3211 pthread_mutex_unlock(&adev->lock);
3212 pthread_mutex_unlock(&in->lock);
3213 /* This mutex was left locked iff in != NULL */
3214 pthread_mutex_unlock(&adev->lock_inputs);
3215 }
3216#endif
3217
3218 return bytes;
3219}
3220
3221static int out_get_render_position(const struct audio_stream_out *stream,
3222 uint32_t *dsp_frames)
3223{
3224 struct stream_out *out = (struct stream_out *)stream;
3225 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003226 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3227 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003228 } else
3229 return -EINVAL;
3230}
3231
3232static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3233{
3234 (void)stream;
3235 (void)effect;
3236 return 0;
3237}
3238
3239static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3240{
3241 (void)stream;
3242 (void)effect;
3243 return 0;
3244}
3245
3246static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3247 int64_t *timestamp)
3248{
3249 (void)stream;
3250 (void)timestamp;
3251 return -EINVAL;
3252}
3253
3254static int out_get_presentation_position(const struct audio_stream_out *stream,
3255 uint64_t *frames, struct timespec *timestamp)
3256{
3257 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003258 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003259
3260 lock_output_stream(out);
3261
3262 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003263 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003264 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003265 if (out->dev->voice.in_call) {
3266 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3267 ret = 0;
3268 goto done;
3269 }
3270
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003271 /* FIXME: which device to read from? */
3272 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003273 struct pcm_device *pcm_device;
3274 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003275 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003276
Andreas Schneiderd6359182017-02-08 16:58:22 +01003277 list_for_each(node, &out->pcm_dev_list) {
3278 pcm_device = node_to_item(node,
3279 struct pcm_device,
3280 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003281
Andreas Schneiderd6359182017-02-08 16:58:22 +01003282 if (pcm_device->pcm != NULL) {
3283 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3284 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3285 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3286 /* This adjustment accounts for buffering after app processor.
3287 It is based on estimated DSP latency per use case, rather than exact. */
3288 signed_frames -=
3289 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3290
3291 /* It would be unusual for this value to be negative, but check just in case ... */
3292 if (signed_frames >= 0) {
3293 *frames = signed_frames;
3294 ret = 0;
3295 goto done;
3296 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003297 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003298 }
3299 }
3300 }
3301 }
3302
Andreas Schneiderd6359182017-02-08 16:58:22 +01003303done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003304 pthread_mutex_unlock(&out->lock);
3305
3306 return ret;
3307}
3308
3309static int out_set_callback(struct audio_stream_out *stream,
3310 stream_callback_t callback, void *cookie)
3311{
3312 struct stream_out *out = (struct stream_out *)stream;
3313
3314 ALOGV("%s", __func__);
3315 lock_output_stream(out);
3316 out->offload_callback = callback;
3317 out->offload_cookie = cookie;
3318 pthread_mutex_unlock(&out->lock);
3319 return 0;
3320}
3321
3322static int out_pause(struct audio_stream_out* stream)
3323{
3324 struct stream_out *out = (struct stream_out *)stream;
3325 int status = -ENOSYS;
3326 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003327 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3328 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003329 return status;
3330}
3331
3332static int out_resume(struct audio_stream_out* stream)
3333{
3334 struct stream_out *out = (struct stream_out *)stream;
3335 int status = -ENOSYS;
3336 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003337 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3338 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003339 return status;
3340}
3341
3342static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3343{
3344 struct stream_out *out = (struct stream_out *)stream;
3345 int status = -ENOSYS;
3346 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003347 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3348 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003349 return status;
3350}
3351
3352static int out_flush(struct audio_stream_out* stream)
3353{
3354 struct stream_out *out = (struct stream_out *)stream;
3355 ALOGV("%s", __func__);
3356 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003357 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003358 }
3359 return -ENOSYS;
3360}
3361
3362/** audio_stream_in implementation **/
3363static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3364{
3365 struct stream_in *in = (struct stream_in *)stream;
3366
3367 return in->requested_rate;
3368}
3369
3370static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3371{
3372 (void)stream;
3373 (void)rate;
3374 return -ENOSYS;
3375}
3376
3377static uint32_t in_get_channels(const struct audio_stream *stream)
3378{
3379 struct stream_in *in = (struct stream_in *)stream;
3380
3381 return in->main_channels;
3382}
3383
3384static audio_format_t in_get_format(const struct audio_stream *stream)
3385{
3386 (void)stream;
3387 return AUDIO_FORMAT_PCM_16_BIT;
3388}
3389
3390static int in_set_format(struct audio_stream *stream, audio_format_t format)
3391{
3392 (void)stream;
3393 (void)format;
3394
3395 return -ENOSYS;
3396}
3397
3398static size_t in_get_buffer_size(const struct audio_stream *stream)
3399{
3400 struct stream_in *in = (struct stream_in *)stream;
3401
3402 return get_input_buffer_size(in->requested_rate,
3403 in_get_format(stream),
3404 audio_channel_count_from_in_mask(in->main_channels),
3405 in->usecase_type,
3406 in->devices);
3407}
3408
3409static int in_close_pcm_devices(struct stream_in *in)
3410{
3411 struct pcm_device *pcm_device;
3412 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003413
3414 list_for_each(node, &in->pcm_dev_list) {
3415 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3416 if (pcm_device) {
3417 if (pcm_device->pcm)
3418 pcm_close(pcm_device->pcm);
3419 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003420 }
3421 }
3422 return 0;
3423}
3424
3425
3426/* must be called with stream and hw device mutex locked */
3427static int do_in_standby_l(struct stream_in *in)
3428{
3429 int status = 0;
3430
3431#ifdef PREPROCESSING_ENABLED
3432 struct audio_device *adev = in->dev;
3433#endif
3434 if (!in->standby) {
3435
3436 in_close_pcm_devices(in);
3437
3438#ifdef PREPROCESSING_ENABLED
3439 if (in->echo_reference != NULL) {
3440 /* stop reading from echo reference */
3441 in->echo_reference->read(in->echo_reference, NULL);
3442 put_echo_reference(adev, in->echo_reference);
3443 in->echo_reference = NULL;
3444 }
3445#ifdef HW_AEC_LOOPBACK
3446 if (in->hw_echo_reference)
3447 {
3448 if (in->hw_ref_buf) {
3449 free(in->hw_ref_buf);
3450 in->hw_ref_buf = NULL;
3451 }
3452 }
3453#endif // HW_AEC_LOOPBACK
3454#endif // PREPROCESSING_ENABLED
3455
3456 status = stop_input_stream(in);
3457
3458 if (in->read_buf) {
3459 free(in->read_buf);
3460 in->read_buf = NULL;
3461 }
3462
3463 in->standby = 1;
3464 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003465
3466 in->last_read_time_us = 0;
3467
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003468 return 0;
3469}
3470
3471// called with adev->lock_inputs locked
3472static int in_standby_l(struct stream_in *in)
3473{
3474 struct audio_device *adev = in->dev;
3475 int status = 0;
3476 lock_input_stream(in);
3477 if (!in->standby) {
3478 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003479 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003480 status = do_in_standby_l(in);
3481 pthread_mutex_unlock(&adev->lock);
3482 }
3483 pthread_mutex_unlock(&in->lock);
3484 return status;
3485}
3486
3487static int in_standby(struct audio_stream *stream)
3488{
3489 struct stream_in *in = (struct stream_in *)stream;
3490 struct audio_device *adev = in->dev;
3491 int status;
3492 ALOGV("%s: enter", __func__);
3493 pthread_mutex_lock(&adev->lock_inputs);
3494 status = in_standby_l(in);
3495 pthread_mutex_unlock(&adev->lock_inputs);
3496 ALOGV("%s: exit: status(%d)", __func__, status);
3497 return status;
3498}
3499
3500static int in_dump(const struct audio_stream *stream, int fd)
3501{
3502 (void)stream;
3503 (void)fd;
3504
3505 return 0;
3506}
3507
3508static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3509{
3510 struct stream_in *in = (struct stream_in *)stream;
3511 struct audio_device *adev = in->dev;
3512 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003513 char value[32];
3514 int ret, val = 0;
3515 struct audio_usecase *uc_info;
3516 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003517 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003518
3519 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3520 parms = str_parms_create_str(kvpairs);
3521
3522 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3523
3524 pthread_mutex_lock(&adev->lock_inputs);
3525 lock_input_stream(in);
3526 pthread_mutex_lock(&adev->lock);
3527 if (ret >= 0) {
3528 val = atoi(value);
3529 /* no audio source uses val == 0 */
3530 if (((int)in->source != val) && (val != 0)) {
3531 in->source = val;
3532 }
3533 }
3534
3535 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3536 if (ret >= 0) {
3537 val = atoi(value);
3538 if (((int)in->devices != val) && (val != 0)) {
3539 in->devices = val;
3540 /* If recording is in progress, change the tx device to new device */
3541 if (!in->standby) {
3542 uc_info = get_usecase_from_id(adev, in->usecase);
3543 if (uc_info == NULL) {
3544 ALOGE("%s: Could not find the usecase (%d) in the list",
3545 __func__, in->usecase);
3546 } else {
3547 if (list_empty(&in->pcm_dev_list))
3548 ALOGE("%s: pcm device list empty", __func__);
3549 else {
3550 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3551 struct pcm_device, stream_list_node);
3552 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3553 do_standby = true;
3554 }
3555 }
3556 }
3557 if (do_standby) {
3558 ret = do_in_standby_l(in);
3559 } else
3560 ret = select_devices(adev, in->usecase);
3561 }
3562 }
3563 }
3564 pthread_mutex_unlock(&adev->lock);
3565 pthread_mutex_unlock(&in->lock);
3566 pthread_mutex_unlock(&adev->lock_inputs);
3567 str_parms_destroy(parms);
3568
3569 if (ret > 0)
3570 ret = 0;
3571
3572 ALOGV("%s: exit: status(%d)", __func__, ret);
3573 return ret;
3574}
3575
3576static char* in_get_parameters(const struct audio_stream *stream,
3577 const char *keys)
3578{
3579 (void)stream;
3580 (void)keys;
3581
3582 return strdup("");
3583}
3584
3585static int in_set_gain(struct audio_stream_in *stream, float gain)
3586{
3587 (void)stream;
3588 (void)gain;
3589
3590 return 0;
3591}
3592
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003593static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3594 size_t bytes)
3595{
3596 struct stream_in *in = (struct stream_in *)stream;
3597 struct audio_device *adev = in->dev;
3598 ssize_t frames = -1;
3599 int ret = -1;
3600 int read_and_process_successful = false;
3601
3602 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003603
3604 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3605 lock_input_stream(in);
3606
Andreas Schneider3b643832017-01-31 11:48:22 +01003607#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003608 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003609 pid_t tid = gettid();
3610 int err;
3611
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003612 err = fast_set_affinity(tid);
3613 if (err < 0) {
3614 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3615 }
3616 in->is_fastcapture_affinity_set = true;
3617 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003618#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003619
3620 if (in->standby) {
3621 pthread_mutex_unlock(&in->lock);
3622 pthread_mutex_lock(&adev->lock_inputs);
3623 lock_input_stream(in);
3624 if (!in->standby) {
3625 pthread_mutex_unlock(&adev->lock_inputs);
3626 goto false_alarm;
3627 }
3628 pthread_mutex_lock(&adev->lock);
3629 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003630 if (ret == 0) {
3631 amplifier_input_stream_start(stream);
3632 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003633 pthread_mutex_unlock(&adev->lock);
3634 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003635
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003636 if (ret != 0) {
3637 goto exit;
3638 }
3639 in->standby = 0;
3640 }
3641false_alarm:
3642
3643 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003644 /*
3645 * Read PCM and:
3646 * - resample if needed
3647 * - process if pre-processors are attached
3648 * - discard unwanted channels
3649 */
3650 frames = read_and_process_frames(in, buffer, frames_rq);
3651 if (frames >= 0)
3652 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003653 }
3654
3655 /*
3656 * Instead of writing zeroes here, we could trust the hardware
3657 * to always provide zeroes when muted.
3658 */
3659 if (read_and_process_successful == true && adev->mic_mute)
3660 memset(buffer, 0, bytes);
3661
3662exit:
3663 pthread_mutex_unlock(&in->lock);
3664
3665 if (read_and_process_successful == false) {
3666 in_standby(&in->stream.common);
3667 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003668 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3669 clock_gettime(CLOCK_MONOTONIC, &t);
3670 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3671
3672 // we do a full sleep when exiting standby.
3673 const bool standby = in->last_read_time_us == 0;
3674 const int64_t elapsed_time_since_last_read = standby ?
3675 0 : now - in->last_read_time_us;
3676 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3677 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3678 if (sleep_time > 0) {
3679 usleep(sleep_time);
3680 } else {
3681 sleep_time = 0;
3682 }
3683 in->last_read_time_us = now + sleep_time;
3684 // last_read_time_us is an approximation of when the (simulated) alsa
3685 // buffer is drained by the read, and is empty.
3686 //
3687 // On the subsequent in_read(), we measure the elapsed time spent in
3688 // the recording thread. This is subtracted from the sleep estimate based on frames,
3689 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003690 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003691 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003692
3693 if (bytes > 0) {
3694 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3695 }
3696
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003697 return bytes;
3698}
3699
3700static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3701{
3702 (void)stream;
3703
3704 return 0;
3705}
3706
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003707static int in_get_capture_position(const struct audio_stream_in *stream,
3708 int64_t *frames, int64_t *time)
3709{
3710 if (stream == NULL || frames == NULL || time == NULL) {
3711 return -EINVAL;
3712 }
3713
3714 struct stream_in *in = (struct stream_in *)stream;
3715 struct pcm_device *pcm_device;
3716 int ret = -ENOSYS;
3717
3718 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3719 struct pcm_device, stream_list_node);
3720
3721 pthread_mutex_lock(&in->lock);
3722 if (pcm_device->pcm) {
3723 struct timespec timestamp;
3724 unsigned int avail;
3725 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3726 *frames = in->frames_read + avail;
3727 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3728 ret = 0;
3729 }
3730 }
3731
3732 pthread_mutex_unlock(&in->lock);
3733 return ret;
3734}
3735
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003736static int add_remove_audio_effect(const struct audio_stream *stream,
3737 effect_handle_t effect,
3738 bool enable)
3739{
3740 struct stream_in *in = (struct stream_in *)stream;
3741 struct audio_device *adev = in->dev;
3742 int status = 0;
3743 effect_descriptor_t desc;
3744#ifdef PREPROCESSING_ENABLED
3745 int i;
3746#endif
3747 status = (*effect)->get_descriptor(effect, &desc);
3748 if (status != 0)
3749 return status;
3750
3751 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3752
3753 pthread_mutex_lock(&adev->lock_inputs);
3754 lock_input_stream(in);
3755 pthread_mutex_lock(&in->dev->lock);
3756#ifndef PREPROCESSING_ENABLED
3757 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3758 in->enable_aec != enable &&
3759 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3760 in->enable_aec = enable;
3761 if (!in->standby)
3762 select_devices(in->dev, in->usecase);
3763 }
3764#else
3765 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3766 status = -ENOSYS;
3767 goto exit;
3768 }
3769 if ( enable == true ) {
3770 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3771 /* add the supported channel of the effect in the channel_configs */
3772 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3773 in->num_preprocessors ++;
3774 /* check compatibility between main channel supported and possible auxiliary channels */
3775 in_update_aux_channels(in, effect);//wesley crash
3776 in->aux_channels_changed = true;
3777 } else {
3778 /* if ( enable == false ) */
3779 if (in->num_preprocessors <= 0) {
3780 status = -ENOSYS;
3781 goto exit;
3782 }
3783 status = -EINVAL;
3784 for (i=0; i < in->num_preprocessors; i++) {
3785 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3786 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3787 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3788 in->preprocessors[i - 1].num_channel_configs =
3789 in->preprocessors[i].num_channel_configs;
3790 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3791 continue;
3792 }
3793 if ( in->preprocessors[i].effect_itfe == effect ) {
3794 ALOGV("add_remove_audio_effect found fx at index %d", i);
3795 free(in->preprocessors[i].channel_configs);
3796 status = 0;
3797 }
3798 }
3799 if (status != 0)
3800 goto exit;
3801 in->num_preprocessors--;
3802 /* if we remove one effect, at least the last proproc should be reset */
3803 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3804 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3805 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3806 in->aux_channels_changed = false;
3807 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3808 }
3809 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3810
3811 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3812 in->enable_aec = enable;
3813 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3814 if (!in->standby) {
3815 select_devices(in->dev, in->usecase);
3816 do_in_standby_l(in);
3817 }
3818 if (in->enable_aec == true) {
3819 in_configure_reverse(in);
3820 }
3821 }
3822exit:
3823#endif
3824 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3825 pthread_mutex_unlock(&in->dev->lock);
3826 pthread_mutex_unlock(&in->lock);
3827 pthread_mutex_unlock(&adev->lock_inputs);
3828 return status;
3829}
3830
3831static int in_add_audio_effect(const struct audio_stream *stream,
3832 effect_handle_t effect)
3833{
3834 ALOGV("%s: effect %p", __func__, effect);
3835 return add_remove_audio_effect(stream, effect, true);
3836}
3837
3838static int in_remove_audio_effect(const struct audio_stream *stream,
3839 effect_handle_t effect)
3840{
3841 ALOGV("%s: effect %p", __func__, effect);
3842 return add_remove_audio_effect(stream, effect, false);
3843}
3844
3845static int adev_open_output_stream(struct audio_hw_device *dev,
3846 audio_io_handle_t handle,
3847 audio_devices_t devices,
3848 audio_output_flags_t flags,
3849 struct audio_config *config,
3850 struct audio_stream_out **stream_out,
3851 const char *address __unused)
3852{
3853 struct audio_device *adev = (struct audio_device *)dev;
3854 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003855 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003856 struct pcm_device_profile *pcm_profile;
3857
3858 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3859 __func__, config->sample_rate, config->channel_mask, devices, flags);
3860 *stream_out = NULL;
3861 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003862 if (out == NULL) {
3863 ret = -ENOMEM;
3864 goto error_config;
3865 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003866
3867 if (devices == AUDIO_DEVICE_NONE)
3868 devices = AUDIO_DEVICE_OUT_SPEAKER;
3869
3870 out->flags = flags;
3871 out->devices = devices;
3872 out->dev = adev;
3873 out->format = config->format;
3874 out->sample_rate = config->sample_rate;
3875 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3876 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3877 out->handle = handle;
3878
3879 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3880 if (pcm_profile == NULL) {
3881 ret = -EINVAL;
3882 goto error_open;
3883 }
3884 out->config = pcm_profile->config;
3885
3886 /* Init use case and pcm_config */
3887 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3888 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3889 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3890 ALOGE("%s: Unsupported Offload information", __func__);
3891 ret = -EINVAL;
3892 goto error_open;
3893 }
3894 if (!is_supported_format(config->offload_info.format)) {
3895 ALOGE("%s: Unsupported audio format", __func__);
3896 ret = -EINVAL;
3897 goto error_open;
3898 }
3899
3900 out->compr_config.codec = (struct snd_codec *)
3901 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003902 if (out->compr_config.codec == NULL) {
3903 ret = -ENOMEM;
3904 goto error_open;
3905 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003906
3907 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3908 if (config->offload_info.channel_mask)
3909 out->channel_mask = config->offload_info.channel_mask;
3910 else if (config->channel_mask)
3911 out->channel_mask = config->channel_mask;
3912 out->format = config->offload_info.format;
3913 out->sample_rate = config->offload_info.sample_rate;
3914
3915 out->stream.set_callback = out_set_callback;
3916 out->stream.pause = out_pause;
3917 out->stream.resume = out_resume;
3918 out->stream.drain = out_drain;
3919 out->stream.flush = out_flush;
3920
3921 out->compr_config.codec->id =
3922 get_snd_codec_id(config->offload_info.format);
3923 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3924 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3925 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3926 out->compr_config.codec->bit_rate =
3927 config->offload_info.bit_rate;
3928 out->compr_config.codec->ch_in =
3929 audio_channel_count_from_out_mask(config->channel_mask);
3930 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3931
3932 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3933 out->non_blocking = 1;
3934
3935 out->send_new_metadata = 1;
3936 create_offload_callback_thread(out);
3937 out->offload_state = OFFLOAD_STATE_IDLE;
3938
3939 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3940 __func__, config->offload_info.version,
3941 config->offload_info.bit_rate);
3942 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3943 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003944 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003945 out->sample_rate = out->config.rate;
3946 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3947 } else {
3948 out->usecase = USECASE_AUDIO_PLAYBACK;
3949 out->sample_rate = out->config.rate;
3950 }
3951
3952 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3953 if (adev->primary_output == NULL)
3954 adev->primary_output = out;
3955 else {
3956 ALOGE("%s: Primary output is already opened", __func__);
3957 ret = -EEXIST;
3958 goto error_open;
3959 }
3960 }
3961
3962 /* Check if this usecase is already existing */
3963 pthread_mutex_lock(&adev->lock);
3964 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3965 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3966 pthread_mutex_unlock(&adev->lock);
3967 ret = -EEXIST;
3968 goto error_open;
3969 }
3970 pthread_mutex_unlock(&adev->lock);
3971
3972 out->stream.common.get_sample_rate = out_get_sample_rate;
3973 out->stream.common.set_sample_rate = out_set_sample_rate;
3974 out->stream.common.get_buffer_size = out_get_buffer_size;
3975 out->stream.common.get_channels = out_get_channels;
3976 out->stream.common.get_format = out_get_format;
3977 out->stream.common.set_format = out_set_format;
3978 out->stream.common.standby = out_standby;
3979 out->stream.common.dump = out_dump;
3980 out->stream.common.set_parameters = out_set_parameters;
3981 out->stream.common.get_parameters = out_get_parameters;
3982 out->stream.common.add_audio_effect = out_add_audio_effect;
3983 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3984 out->stream.get_latency = out_get_latency;
3985 out->stream.set_volume = out_set_volume;
3986 out->stream.write = out_write;
3987 out->stream.get_render_position = out_get_render_position;
3988 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3989 out->stream.get_presentation_position = out_get_presentation_position;
3990
3991 out->standby = 1;
3992 /* out->muted = false; by calloc() */
3993 /* out->written = 0; by calloc() */
3994
3995 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3996 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3997 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3998
3999 config->format = out->stream.common.get_format(&out->stream.common);
4000 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
4001 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
4002
4003 out->is_fastmixer_affinity_set = false;
4004
4005 *stream_out = &out->stream;
4006 ALOGV("%s: exit", __func__);
4007 return 0;
4008
4009error_open:
4010 free(out);
4011 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01004012error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004013 ALOGV("%s: exit: ret %d", __func__, ret);
4014 return ret;
4015}
4016
4017static void adev_close_output_stream(struct audio_hw_device *dev,
4018 struct audio_stream_out *stream)
4019{
4020 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004021 (void)dev;
4022
4023 ALOGV("%s: enter", __func__);
4024 out_standby(&stream->common);
4025 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
4026 destroy_offload_callback_thread(out);
4027
4028 if (out->compr_config.codec != NULL)
4029 free(out->compr_config.codec);
4030 }
4031 pthread_cond_destroy(&out->cond);
4032 pthread_mutex_destroy(&out->lock);
4033 free(stream);
4034 ALOGV("%s: exit", __func__);
4035}
4036
4037static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
4038{
4039 struct audio_device *adev = (struct audio_device *)dev;
4040 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004041 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004042#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004043 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01004044#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004045 int ret;
4046
4047 ALOGV("%s: enter: %s", __func__, kvpairs);
4048
4049 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004050
Andreas Schneider05bc1882017-02-09 14:03:11 +01004051 /******************************************************
4052 *** BT SCO
4053 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004054 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
4055 if (ret >= 0) {
4056 /* When set to false, HAL should disable EC and NS
4057 * But it is currently not supported.
4058 */
4059 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004060 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004061 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004062 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004063 }
4064
Andreas Schneider05bc1882017-02-09 14:03:11 +01004065 ret = str_parms_get_str(parms,
4066 AUDIO_PARAMETER_KEY_BT_SCO_WB,
4067 value,
4068 sizeof(value));
4069 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01004070 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
4071 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01004072 } else {
4073 adev->voice.bluetooth_wb = false;
4074 }
4075 }
4076
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01004077 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
4078 if (ret >= 0) {
4079 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
4080 adev->screen_off = false;
4081 else
4082 adev->screen_off = true;
4083 }
4084
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004085#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004086 ret = str_parms_get_int(parms, "rotation", &val);
4087 if (ret >= 0) {
4088 bool reverse_speakers = false;
4089 switch(val) {
4090 /* FIXME: note that the code below assumes that the speakers are in the correct placement
4091 relative to the user when the device is rotated 90deg from its default rotation. This
4092 assumption is device-specific, not platform-specific like this code. */
4093 case 270:
4094 reverse_speakers = true;
4095 break;
4096 case 0:
4097 case 90:
4098 case 180:
4099 break;
4100 default:
4101 ALOGE("%s: unexpected rotation of %d", __func__, val);
4102 }
4103 pthread_mutex_lock(&adev->lock);
4104 if (adev->speaker_lr_swap != reverse_speakers) {
4105 adev->speaker_lr_swap = reverse_speakers;
4106 /* only update the selected device if there is active pcm playback */
4107 struct audio_usecase *usecase;
4108 struct listnode *node;
4109 list_for_each(node, &adev->usecase_list) {
4110 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
4111 if (usecase->type == PCM_PLAYBACK) {
4112 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004113 break;
4114 }
4115 }
4116 }
4117 pthread_mutex_unlock(&adev->lock);
4118 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01004119#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004120
4121 str_parms_destroy(parms);
4122
4123 if (ret > 0)
4124 ret = 0;
4125
4126 ALOGV("%s: exit with code(%d)", __func__, ret);
4127 return ret;
4128}
4129
4130static char* adev_get_parameters(const struct audio_hw_device *dev,
4131 const char *keys)
4132{
4133 (void)dev;
4134 (void)keys;
4135
4136 return strdup("");
4137}
4138
4139static int adev_init_check(const struct audio_hw_device *dev)
4140{
4141 (void)dev;
4142
4143 return 0;
4144}
4145
4146static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4147{
4148 int ret = 0;
4149 struct audio_device *adev = (struct audio_device *)dev;
4150 pthread_mutex_lock(&adev->lock);
4151 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004152 adev->voice.volume = volume;
4153 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004154 pthread_mutex_unlock(&adev->lock);
4155 return ret;
4156}
4157
4158static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4159{
4160 (void)dev;
4161 (void)volume;
4162
4163 return -ENOSYS;
4164}
4165
4166static int adev_get_master_volume(struct audio_hw_device *dev,
4167 float *volume)
4168{
4169 (void)dev;
4170 (void)volume;
4171
4172 return -ENOSYS;
4173}
4174
4175static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4176{
4177 (void)dev;
4178 (void)muted;
4179
4180 return -ENOSYS;
4181}
4182
4183static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4184{
4185 (void)dev;
4186 (void)muted;
4187
4188 return -ENOSYS;
4189}
4190
4191static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4192{
4193 struct audio_device *adev = (struct audio_device *)dev;
4194
4195 pthread_mutex_lock(&adev->lock);
4196 if (adev->mode != mode) {
4197 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004198 if (amplifier_set_mode(mode) != 0) {
4199 ALOGE("Failed setting amplifier mode");
4200 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004201 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004202
4203 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4204 stop_voice_call(adev);
4205 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004206 }
4207 pthread_mutex_unlock(&adev->lock);
4208 return 0;
4209}
4210
4211static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4212{
4213 struct audio_device *adev = (struct audio_device *)dev;
4214 int err = 0;
4215
4216 pthread_mutex_lock(&adev->lock);
4217 adev->mic_mute = state;
4218
4219 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004220 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004221 }
4222
4223 pthread_mutex_unlock(&adev->lock);
4224 return err;
4225}
4226
4227static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4228{
4229 struct audio_device *adev = (struct audio_device *)dev;
4230
4231 *state = adev->mic_mute;
4232
4233 return 0;
4234}
4235
4236static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4237 const struct audio_config *config)
4238{
4239 (void)dev;
4240
4241 /* NOTE: we default to built in mic which may cause a mismatch between what we
4242 * report here and the actual buffer size
4243 */
4244 return get_input_buffer_size(config->sample_rate,
4245 config->format,
4246 audio_channel_count_from_in_mask(config->channel_mask),
4247 PCM_CAPTURE /* usecase_type */,
4248 AUDIO_DEVICE_IN_BUILTIN_MIC);
4249}
4250
4251static int adev_open_input_stream(struct audio_hw_device *dev,
4252 audio_io_handle_t handle __unused,
4253 audio_devices_t devices,
4254 struct audio_config *config,
4255 struct audio_stream_in **stream_in,
4256 audio_input_flags_t flags,
4257 const char *address __unused,
4258 audio_source_t source)
4259{
4260 struct audio_device *adev = (struct audio_device *)dev;
4261 struct stream_in *in;
4262 struct pcm_device_profile *pcm_profile;
4263
4264 ALOGV("%s: enter", __func__);
4265
4266 *stream_in = NULL;
4267 if (check_input_parameters(config->sample_rate, config->format,
4268 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4269 return -EINVAL;
4270
stenkinevgeniy44335362018-05-07 18:00:13 +00004271 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004272 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4273 pcm_profile = get_pcm_device(usecase_type, devices);
4274 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4275 // a low latency profile may not exist for that device, fall back
4276 // to regular capture. the MixerThread automatically changes
4277 // to non-fast capture based on the buffer size.
4278 flags &= ~AUDIO_INPUT_FLAG_FAST;
4279 usecase_type = PCM_CAPTURE;
4280 pcm_profile = get_pcm_device(usecase_type, devices);
4281 }
4282 if (pcm_profile == NULL)
4283 return -EINVAL;
4284
4285 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004286 if (in == NULL) {
4287 return -ENOMEM;
4288 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004289
4290 in->stream.common.get_sample_rate = in_get_sample_rate;
4291 in->stream.common.set_sample_rate = in_set_sample_rate;
4292 in->stream.common.get_buffer_size = in_get_buffer_size;
4293 in->stream.common.get_channels = in_get_channels;
4294 in->stream.common.get_format = in_get_format;
4295 in->stream.common.set_format = in_set_format;
4296 in->stream.common.standby = in_standby;
4297 in->stream.common.dump = in_dump;
4298 in->stream.common.set_parameters = in_set_parameters;
4299 in->stream.common.get_parameters = in_get_parameters;
4300 in->stream.common.add_audio_effect = in_add_audio_effect;
4301 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4302 in->stream.set_gain = in_set_gain;
4303 in->stream.read = in_read;
4304 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004305 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004306
4307 in->devices = devices;
4308 in->source = source;
4309 in->dev = adev;
4310 in->standby = 1;
4311 in->main_channels = config->channel_mask;
4312 in->requested_rate = config->sample_rate;
4313 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4314 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4315 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004316 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004317 /* HW codec is limited to default channels. No need to update with
4318 * requested channels */
4319 in->config = pcm_profile->config;
4320
4321 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004322 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004323 in->usecase_type = usecase_type;
4324
4325 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4326 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4327
4328 in->is_fastcapture_affinity_set = false;
4329
4330 *stream_in = &in->stream;
4331 ALOGV("%s: exit", __func__);
4332 return 0;
4333}
4334
4335static void adev_close_input_stream(struct audio_hw_device *dev,
4336 struct audio_stream_in *stream)
4337{
4338 struct audio_device *adev = (struct audio_device *)dev;
4339 struct stream_in *in = (struct stream_in*)stream;
4340 ALOGV("%s", __func__);
4341
4342 /* prevent concurrent out_set_parameters, or out_write from standby */
4343 pthread_mutex_lock(&adev->lock_inputs);
4344
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004345 if (in->read_buf) {
4346 free(in->read_buf);
4347 in->read_buf = NULL;
4348 }
4349
4350 if (in->resampler) {
4351 release_resampler(in->resampler);
4352 in->resampler = NULL;
4353 }
4354
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004355#ifdef PREPROCESSING_ENABLED
4356 int i;
4357
4358 for (i=0; i<in->num_preprocessors; i++) {
4359 free(in->preprocessors[i].channel_configs);
4360 }
4361
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004362 if (in->proc_buf_in) {
4363 free(in->proc_buf_in);
4364 in->proc_buf_in = NULL;
4365 }
4366
4367 if (in->proc_buf_out) {
4368 free(in->proc_buf_out);
4369 in->proc_buf_out = NULL;
4370 }
4371
4372 if (in->ref_buf) {
4373 free(in->ref_buf);
4374 in->ref_buf = NULL;
4375 }
4376
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004377#endif
4378
4379 in_standby_l(in);
4380 free(stream);
4381
4382 pthread_mutex_unlock(&adev->lock_inputs);
4383
4384 return;
4385}
4386
4387static int adev_dump(const audio_hw_device_t *device, int fd)
4388{
4389 (void)device;
4390 (void)fd;
4391
4392 return 0;
4393}
4394
4395static int adev_close(hw_device_t *device)
4396{
4397 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004398 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004399 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004400 if (audio_device_ref_count == 0) {
4401 if (amplifier_close() != 0) {
4402 ALOGE("Amplifier close failed");
4403 }
4404 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004405 free(adev->snd_dev_ref_cnt);
4406 free_mixer_list(adev);
4407 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004408
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004409 adev = NULL;
4410
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004411 return 0;
4412}
4413
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004414/* This returns true if the input parameter looks at all plausible as a low latency period size,
4415 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4416 * just that it _might_ work.
4417 */
4418static bool period_size_is_plausible_for_low_latency(int period_size)
4419{
4420 switch (period_size) {
4421 case 64:
4422 case 96:
4423 case 128:
4424 case 192:
4425 case 256:
4426 return true;
4427 default:
4428 return false;
4429 }
4430}
4431
4432static int adev_open(const hw_module_t *module, const char *name,
4433 hw_device_t **device)
4434{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004435 ALOGV("%s: enter", __func__);
4436 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4437
Andreas Schneider56204f62017-01-31 08:17:32 +01004438 *device = NULL;
4439
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004440 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004441 if (adev == NULL) {
4442 return -ENOMEM;
4443 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004444
4445 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4446 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4447 adev->device.common.module = (struct hw_module_t *)module;
4448 adev->device.common.close = adev_close;
4449
4450 adev->device.init_check = adev_init_check;
4451 adev->device.set_voice_volume = adev_set_voice_volume;
4452 adev->device.set_master_volume = adev_set_master_volume;
4453 adev->device.get_master_volume = adev_get_master_volume;
4454 adev->device.set_master_mute = adev_set_master_mute;
4455 adev->device.get_master_mute = adev_get_master_mute;
4456 adev->device.set_mode = adev_set_mode;
4457 adev->device.set_mic_mute = adev_set_mic_mute;
4458 adev->device.get_mic_mute = adev_get_mic_mute;
4459 adev->device.set_parameters = adev_set_parameters;
4460 adev->device.get_parameters = adev_get_parameters;
4461 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4462 adev->device.open_output_stream = adev_open_output_stream;
4463 adev->device.close_output_stream = adev_close_output_stream;
4464 adev->device.open_input_stream = adev_open_input_stream;
4465 adev->device.close_input_stream = adev_close_input_stream;
4466 adev->device.dump = adev_dump;
4467
4468 /* Set the default route before the PCM stream is opened */
4469 adev->mode = AUDIO_MODE_NORMAL;
4470 adev->active_input = NULL;
4471 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004472
4473 adev->voice.volume = 1.0f;
4474 adev->voice.bluetooth_nrec = true;
4475 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004476 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004477
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004478 /* adev->cur_hdmi_channels = 0; by calloc() */
4479 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004480 if (adev->snd_dev_ref_cnt == NULL) {
4481 free(adev);
4482 return -ENOMEM;
4483 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004484
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004485 adev->ns_in_voice_rec = false;
4486
4487 list_init(&adev->usecase_list);
4488
4489 if (mixer_init(adev) != 0) {
4490 free(adev->snd_dev_ref_cnt);
4491 free(adev);
4492 ALOGE("%s: Failed to init, aborting.", __func__);
4493 *device = NULL;
4494 return -EINVAL;
4495 }
4496
4497 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4498 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4499 if (adev->offload_fx_lib == NULL) {
4500 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4501 } else {
4502 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4503 adev->offload_fx_start_output =
4504 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4505 "visualizer_hal_start_output");
4506 adev->offload_fx_stop_output =
4507 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4508 "visualizer_hal_stop_output");
4509 }
4510 }
4511
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004512 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004513 if (adev->voice.session == NULL) {
4514 ALOGE("%s: Failed to initialize voice session data", __func__);
4515
4516 free(adev->snd_dev_ref_cnt);
4517 free(adev);
4518
4519 *device = NULL;
4520 return -EINVAL;
4521 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004522
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004523 if (amplifier_open() != 0) {
4524 ALOGE("Amplifier initialization failed");
4525 }
4526
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004527 *device = &adev->device.common;
4528
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004529 audio_device_ref_count++;
4530
4531 char value[PROPERTY_VALUE_MAX];
4532 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4533 int trial = atoi(value);
4534 if (period_size_is_plausible_for_low_latency(trial)) {
4535
4536 pcm_device_playback.config.period_size = trial;
4537 pcm_device_playback.config.start_threshold =
4538 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4539 pcm_device_playback.config.stop_threshold =
4540 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4541
4542 pcm_device_capture_low_latency.config.period_size = trial;
4543 }
4544 }
4545
4546 ALOGV("%s: exit", __func__);
4547 return 0;
4548}
4549
4550static struct hw_module_methods_t hal_module_methods = {
4551 .open = adev_open,
4552};
4553
4554struct audio_module HAL_MODULE_INFO_SYM = {
4555 .common = {
4556 .tag = HARDWARE_MODULE_TAG,
4557 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4558 .hal_api_version = HARDWARE_HAL_API_VERSION,
4559 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004560 .name = "Samsung Audio HAL",
4561 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004562 .methods = &hal_module_methods,
4563 },
4564};