audio_hw.c revision c38e452918fd27b410a40be44132db32090dfced
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "audio_hw_primary" 18/*#define LOG_NDEBUG 0*/ 19/*#define VERY_VERY_VERBOSE_LOGGING*/ 20#ifdef VERY_VERY_VERBOSE_LOGGING 21#define ALOGVV ALOGV 22#else 23#define ALOGVV(a...) do { } while(0) 24#endif 25 26#include <errno.h> 27#include <pthread.h> 28#include <stdint.h> 29#include <sys/time.h> 30#include <stdlib.h> 31#include <math.h> 32#include <dlfcn.h> 33#include <sys/resource.h> 34#include <sys/prctl.h> 35 36#include <cutils/log.h> 37#include <cutils/str_parms.h> 38#include <cutils/properties.h> 39#include <cutils/atomic.h> 40#include <cutils/sched_policy.h> 41 42#include <hardware/audio_effect.h> 43#include <hardware/audio_alsaops.h> 44#include <system/thread_defs.h> 45#include <audio_effects/effect_aec.h> 46#include <audio_effects/effect_ns.h> 47#include "audio_hw.h" 48#include "platform_api.h" 49#include <platform.h> 50 51#include "sound/compress_params.h" 52 53#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024) 54#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4 55/* ToDo: Check and update a proper value in msec */ 56#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96 57#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000 58 59/* This constant enables extended precision handling. 60 * TODO The flag is off until more testing is done. 61 */ 62static const bool k_enable_extended_precision = false; 63 64struct pcm_config pcm_config_deep_buffer = { 65 .channels = 2, 66 .rate = DEFAULT_OUTPUT_SAMPLING_RATE, 67 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE, 68 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT, 69 .format = PCM_FORMAT_S16_LE, 70 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4, 71 .stop_threshold = INT_MAX, 72 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4, 73}; 74 75struct pcm_config pcm_config_low_latency = { 76 .channels = 2, 77 .rate = DEFAULT_OUTPUT_SAMPLING_RATE, 78 .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE, 79 .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT, 80 .format = PCM_FORMAT_S16_LE, 81 .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4, 82 .stop_threshold = INT_MAX, 83 .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4, 84}; 85 86struct pcm_config pcm_config_hdmi_multi = { 87 .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */ 88 .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */ 89 .period_size = HDMI_MULTI_PERIOD_SIZE, 90 .period_count = HDMI_MULTI_PERIOD_COUNT, 91 .format = PCM_FORMAT_S16_LE, 92 .start_threshold = 0, 93 .stop_threshold = INT_MAX, 94 .avail_min = 0, 95}; 96 97struct pcm_config pcm_config_audio_capture = { 98 .channels = 2, 99 .period_count = AUDIO_CAPTURE_PERIOD_COUNT, 100 .format = PCM_FORMAT_S16_LE, 101}; 102 103struct pcm_config pcm_config_voice_call = { 104 .channels = 1, 105 .rate = 8000, 106 .period_size = 160, 107 .period_count = 2, 108 .format = PCM_FORMAT_S16_LE, 109}; 110 111static const char * const use_case_table[AUDIO_USECASE_MAX] = { 112 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback", 113 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback", 114 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback", 115 [USECASE_AUDIO_RECORD] = "audio-record", 116 [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record", 117 [USECASE_VOICE_CALL] = "voice-call", 118 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback", 119}; 120 121 122#define STRING_TO_ENUM(string) { #string, string } 123 124struct string_to_enum { 125 const char *name; 126 uint32_t value; 127}; 128 129static const struct string_to_enum out_channels_name_to_enum_table[] = { 130 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 131 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 132 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 133}; 134 135static int set_voice_volume_l(struct audio_device *adev, float volume); 136 137static bool is_supported_format(audio_format_t format) 138{ 139 if (format == AUDIO_FORMAT_MP3 || 140 format == AUDIO_FORMAT_AAC) 141 return true; 142 143 return false; 144} 145 146static int get_snd_codec_id(audio_format_t format) 147{ 148 int id = 0; 149 150 switch (format) { 151 case AUDIO_FORMAT_MP3: 152 id = SND_AUDIOCODEC_MP3; 153 break; 154 case AUDIO_FORMAT_AAC: 155 id = SND_AUDIOCODEC_AAC; 156 break; 157 default: 158 ALOGE("%s: Unsupported audio format", __func__); 159 } 160 161 return id; 162} 163 164static int enable_audio_route(struct audio_device *adev, 165 struct audio_usecase *usecase) 166{ 167 snd_device_t snd_device; 168 char mixer_path[50]; 169 170 if (usecase == NULL) 171 return -EINVAL; 172 173 ALOGV("%s: enter: usecase(%d)", __func__, usecase->id); 174 175 if (usecase->type == PCM_CAPTURE) 176 snd_device = usecase->in_snd_device; 177 else 178 snd_device = usecase->out_snd_device; 179 180 strcpy(mixer_path, use_case_table[usecase->id]); 181 platform_add_backend_name(mixer_path, snd_device); 182 ALOGV("%s: apply and update mixer path: %s", __func__, mixer_path); 183 audio_route_apply_and_update_path(adev->audio_route, mixer_path); 184 185 ALOGV("%s: exit", __func__); 186 return 0; 187} 188 189static int disable_audio_route(struct audio_device *adev, 190 struct audio_usecase *usecase) 191{ 192 snd_device_t snd_device; 193 char mixer_path[50]; 194 195 if (usecase == NULL) 196 return -EINVAL; 197 198 ALOGV("%s: enter: usecase(%d)", __func__, usecase->id); 199 if (usecase->type == PCM_CAPTURE) 200 snd_device = usecase->in_snd_device; 201 else 202 snd_device = usecase->out_snd_device; 203 strcpy(mixer_path, use_case_table[usecase->id]); 204 platform_add_backend_name(mixer_path, snd_device); 205 ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path); 206 audio_route_reset_and_update_path(adev->audio_route, mixer_path); 207 208 ALOGV("%s: exit", __func__); 209 return 0; 210} 211 212static int enable_snd_device(struct audio_device *adev, 213 snd_device_t snd_device) 214{ 215 if (snd_device < SND_DEVICE_MIN || 216 snd_device >= SND_DEVICE_MAX) { 217 ALOGE("%s: Invalid sound device %d", __func__, snd_device); 218 return -EINVAL; 219 } 220 221 adev->snd_dev_ref_cnt[snd_device]++; 222 if (adev->snd_dev_ref_cnt[snd_device] > 1) { 223 ALOGV("%s: snd_device(%d: %s) is already active", 224 __func__, snd_device, platform_get_snd_device_name(snd_device)); 225 return 0; 226 } 227 228 if (platform_send_audio_calibration(adev->platform, snd_device) < 0) { 229 adev->snd_dev_ref_cnt[snd_device]--; 230 return -EINVAL; 231 } 232 233 const char * dev_path = platform_get_snd_device_name(snd_device); 234 ALOGV("%s: snd_device(%d: %s)", __func__, snd_device, dev_path); 235 audio_route_apply_and_update_path(adev->audio_route, dev_path); 236 237 return 0; 238} 239 240static int disable_snd_device(struct audio_device *adev, 241 snd_device_t snd_device) 242{ 243 if (snd_device < SND_DEVICE_MIN || 244 snd_device >= SND_DEVICE_MAX) { 245 ALOGE("%s: Invalid sound device %d", __func__, snd_device); 246 return -EINVAL; 247 } 248 if (adev->snd_dev_ref_cnt[snd_device] <= 0) { 249 ALOGE("%s: device ref cnt is already 0", __func__); 250 return -EINVAL; 251 } 252 adev->snd_dev_ref_cnt[snd_device]--; 253 if (adev->snd_dev_ref_cnt[snd_device] == 0) { 254 const char * dev_path = platform_get_snd_device_name(snd_device); 255 ALOGV("%s: snd_device(%d: %s)", __func__, 256 snd_device, dev_path); 257 audio_route_reset_and_update_path(adev->audio_route, dev_path); 258 } 259 return 0; 260} 261 262static void check_usecases_codec_backend(struct audio_device *adev, 263 struct audio_usecase *uc_info, 264 snd_device_t snd_device) 265{ 266 struct listnode *node; 267 struct audio_usecase *usecase; 268 bool switch_device[AUDIO_USECASE_MAX]; 269 int i, num_uc_to_switch = 0; 270 271 /* 272 * This function is to make sure that all the usecases that are active on 273 * the hardware codec backend are always routed to any one device that is 274 * handled by the hardware codec. 275 * For example, if low-latency and deep-buffer usecases are currently active 276 * on speaker and out_set_parameters(headset) is received on low-latency 277 * output, then we have to make sure deep-buffer is also switched to headset, 278 * because of the limitation that both the devices cannot be enabled 279 * at the same time as they share the same backend. 280 */ 281 /* Disable all the usecases on the shared backend other than the 282 specified usecase */ 283 for (i = 0; i < AUDIO_USECASE_MAX; i++) 284 switch_device[i] = false; 285 286 list_for_each(node, &adev->usecase_list) { 287 usecase = node_to_item(node, struct audio_usecase, list); 288 if (usecase->type != PCM_CAPTURE && 289 usecase != uc_info && 290 usecase->out_snd_device != snd_device && 291 usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) { 292 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..", 293 __func__, use_case_table[usecase->id], 294 platform_get_snd_device_name(usecase->out_snd_device)); 295 disable_audio_route(adev, usecase); 296 switch_device[usecase->id] = true; 297 num_uc_to_switch++; 298 } 299 } 300 301 if (num_uc_to_switch) { 302 list_for_each(node, &adev->usecase_list) { 303 usecase = node_to_item(node, struct audio_usecase, list); 304 if (switch_device[usecase->id]) { 305 disable_snd_device(adev, usecase->out_snd_device); 306 } 307 } 308 309 list_for_each(node, &adev->usecase_list) { 310 usecase = node_to_item(node, struct audio_usecase, list); 311 if (switch_device[usecase->id]) { 312 enable_snd_device(adev, snd_device); 313 } 314 } 315 316 /* Re-route all the usecases on the shared backend other than the 317 specified usecase to new snd devices */ 318 list_for_each(node, &adev->usecase_list) { 319 usecase = node_to_item(node, struct audio_usecase, list); 320 /* Update the out_snd_device only before enabling the audio route */ 321 if (switch_device[usecase->id] ) { 322 usecase->out_snd_device = snd_device; 323 enable_audio_route(adev, usecase); 324 } 325 } 326 } 327} 328 329static void check_and_route_capture_usecases(struct audio_device *adev, 330 struct audio_usecase *uc_info, 331 snd_device_t snd_device) 332{ 333 struct listnode *node; 334 struct audio_usecase *usecase; 335 bool switch_device[AUDIO_USECASE_MAX]; 336 int i, num_uc_to_switch = 0; 337 338 /* 339 * This function is to make sure that all the active capture usecases 340 * are always routed to the same input sound device. 341 * For example, if audio-record and voice-call usecases are currently 342 * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece) 343 * is received for voice call then we have to make sure that audio-record 344 * usecase is also switched to earpiece i.e. voice-dmic-ef, 345 * because of the limitation that two devices cannot be enabled 346 * at the same time if they share the same backend. 347 */ 348 for (i = 0; i < AUDIO_USECASE_MAX; i++) 349 switch_device[i] = false; 350 351 list_for_each(node, &adev->usecase_list) { 352 usecase = node_to_item(node, struct audio_usecase, list); 353 if (usecase->type != PCM_PLAYBACK && 354 usecase != uc_info && 355 usecase->in_snd_device != snd_device) { 356 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..", 357 __func__, use_case_table[usecase->id], 358 platform_get_snd_device_name(usecase->in_snd_device)); 359 disable_audio_route(adev, usecase); 360 switch_device[usecase->id] = true; 361 num_uc_to_switch++; 362 } 363 } 364 365 if (num_uc_to_switch) { 366 list_for_each(node, &adev->usecase_list) { 367 usecase = node_to_item(node, struct audio_usecase, list); 368 if (switch_device[usecase->id]) { 369 disable_snd_device(adev, usecase->in_snd_device); 370 enable_snd_device(adev, snd_device); 371 } 372 } 373 374 /* Re-route all the usecases on the shared backend other than the 375 specified usecase to new snd devices */ 376 list_for_each(node, &adev->usecase_list) { 377 usecase = node_to_item(node, struct audio_usecase, list); 378 /* Update the in_snd_device only before enabling the audio route */ 379 if (switch_device[usecase->id] ) { 380 usecase->in_snd_device = snd_device; 381 enable_audio_route(adev, usecase); 382 } 383 } 384 } 385} 386 387 388/* must be called with hw device mutex locked */ 389static int read_hdmi_channel_masks(struct stream_out *out) 390{ 391 int ret = 0; 392 int channels = platform_edid_get_max_channels(out->dev->platform); 393 394 switch (channels) { 395 /* 396 * Do not handle stereo output in Multi-channel cases 397 * Stereo case is handled in normal playback path 398 */ 399 case 6: 400 ALOGV("%s: HDMI supports 5.1", __func__); 401 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1; 402 break; 403 case 8: 404 ALOGV("%s: HDMI supports 5.1 and 7.1 channels", __func__); 405 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1; 406 out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1; 407 break; 408 default: 409 ALOGE("HDMI does not support multi channel playback"); 410 ret = -ENOSYS; 411 break; 412 } 413 return ret; 414} 415 416static struct audio_usecase *get_usecase_from_list(struct audio_device *adev, 417 audio_usecase_t uc_id) 418{ 419 struct audio_usecase *usecase; 420 struct listnode *node; 421 422 list_for_each(node, &adev->usecase_list) { 423 usecase = node_to_item(node, struct audio_usecase, list); 424 if (usecase->id == uc_id) 425 return usecase; 426 } 427 return NULL; 428} 429 430static int select_devices(struct audio_device *adev, 431 audio_usecase_t uc_id) 432{ 433 snd_device_t out_snd_device = SND_DEVICE_NONE; 434 snd_device_t in_snd_device = SND_DEVICE_NONE; 435 struct audio_usecase *usecase = NULL; 436 struct audio_usecase *vc_usecase = NULL; 437 struct listnode *node; 438 int status = 0; 439 440 usecase = get_usecase_from_list(adev, uc_id); 441 if (usecase == NULL) { 442 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id); 443 return -EINVAL; 444 } 445 446 if (usecase->type == VOICE_CALL) { 447 out_snd_device = platform_get_output_snd_device(adev->platform, 448 usecase->stream.out->devices); 449 in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices); 450 usecase->devices = usecase->stream.out->devices; 451 } else { 452 /* 453 * If the voice call is active, use the sound devices of voice call usecase 454 * so that it would not result any device switch. All the usecases will 455 * be switched to new device when select_devices() is called for voice call 456 * usecase. This is to avoid switching devices for voice call when 457 * check_usecases_codec_backend() is called below. 458 */ 459 if (adev->in_call) { 460 vc_usecase = get_usecase_from_list(adev, USECASE_VOICE_CALL); 461 if (vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) { 462 in_snd_device = vc_usecase->in_snd_device; 463 out_snd_device = vc_usecase->out_snd_device; 464 } 465 } 466 if (usecase->type == PCM_PLAYBACK) { 467 usecase->devices = usecase->stream.out->devices; 468 in_snd_device = SND_DEVICE_NONE; 469 if (out_snd_device == SND_DEVICE_NONE) { 470 out_snd_device = platform_get_output_snd_device(adev->platform, 471 usecase->stream.out->devices); 472 if (usecase->stream.out == adev->primary_output && 473 adev->active_input && 474 adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) { 475 select_devices(adev, adev->active_input->usecase); 476 } 477 } 478 } else if (usecase->type == PCM_CAPTURE) { 479 usecase->devices = usecase->stream.in->device; 480 out_snd_device = SND_DEVICE_NONE; 481 if (in_snd_device == SND_DEVICE_NONE) { 482 if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION && 483 adev->primary_output && !adev->primary_output->standby) { 484 in_snd_device = platform_get_input_snd_device(adev->platform, 485 adev->primary_output->devices); 486 } else { 487 in_snd_device = platform_get_input_snd_device(adev->platform, 488 AUDIO_DEVICE_NONE); 489 } 490 } 491 } 492 } 493 494 if (out_snd_device == usecase->out_snd_device && 495 in_snd_device == usecase->in_snd_device) { 496 return 0; 497 } 498 499 ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__, 500 out_snd_device, platform_get_snd_device_name(out_snd_device), 501 in_snd_device, platform_get_snd_device_name(in_snd_device)); 502 503 /* 504 * Limitation: While in call, to do a device switch we need to disable 505 * and enable both RX and TX devices though one of them is same as current 506 * device. 507 */ 508 if (usecase->type == VOICE_CALL) { 509 status = platform_switch_voice_call_device_pre(adev->platform); 510 } 511 512 /* Disable current sound devices */ 513 if (usecase->out_snd_device != SND_DEVICE_NONE) { 514 disable_audio_route(adev, usecase); 515 disable_snd_device(adev, usecase->out_snd_device); 516 } 517 518 if (usecase->in_snd_device != SND_DEVICE_NONE) { 519 disable_audio_route(adev, usecase); 520 disable_snd_device(adev, usecase->in_snd_device); 521 } 522 523 /* Enable new sound devices */ 524 if (out_snd_device != SND_DEVICE_NONE) { 525 if (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) 526 check_usecases_codec_backend(adev, usecase, out_snd_device); 527 enable_snd_device(adev, out_snd_device); 528 } 529 530 if (in_snd_device != SND_DEVICE_NONE) { 531 check_and_route_capture_usecases(adev, usecase, in_snd_device); 532 enable_snd_device(adev, in_snd_device); 533 } 534 535 if (usecase->type == VOICE_CALL) 536 status = platform_switch_voice_call_device_post(adev->platform, 537 out_snd_device, 538 in_snd_device); 539 540 usecase->in_snd_device = in_snd_device; 541 usecase->out_snd_device = out_snd_device; 542 543 enable_audio_route(adev, usecase); 544 545 return status; 546} 547 548static int stop_input_stream(struct stream_in *in) 549{ 550 int i, ret = 0; 551 struct audio_usecase *uc_info; 552 struct audio_device *adev = in->dev; 553 554 adev->active_input = NULL; 555 556 ALOGV("%s: enter: usecase(%d: %s)", __func__, 557 in->usecase, use_case_table[in->usecase]); 558 uc_info = get_usecase_from_list(adev, in->usecase); 559 if (uc_info == NULL) { 560 ALOGE("%s: Could not find the usecase (%d) in the list", 561 __func__, in->usecase); 562 return -EINVAL; 563 } 564 565 /* 1. Disable stream specific mixer controls */ 566 disable_audio_route(adev, uc_info); 567 568 /* 2. Disable the tx device */ 569 disable_snd_device(adev, uc_info->in_snd_device); 570 571 list_remove(&uc_info->list); 572 free(uc_info); 573 574 ALOGV("%s: exit: status(%d)", __func__, ret); 575 return ret; 576} 577 578int start_input_stream(struct stream_in *in) 579{ 580 /* 1. Enable output device and stream routing controls */ 581 int ret = 0; 582 struct audio_usecase *uc_info; 583 struct audio_device *adev = in->dev; 584 585 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase); 586 in->pcm_device_id = platform_get_pcm_device_id(in->usecase, PCM_CAPTURE); 587 if (in->pcm_device_id < 0) { 588 ALOGE("%s: Could not find PCM device id for the usecase(%d)", 589 __func__, in->usecase); 590 ret = -EINVAL; 591 goto error_config; 592 } 593 594 adev->active_input = in; 595 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); 596 uc_info->id = in->usecase; 597 uc_info->type = PCM_CAPTURE; 598 uc_info->stream.in = in; 599 uc_info->devices = in->device; 600 uc_info->in_snd_device = SND_DEVICE_NONE; 601 uc_info->out_snd_device = SND_DEVICE_NONE; 602 603 list_add_tail(&adev->usecase_list, &uc_info->list); 604 select_devices(adev, in->usecase); 605 606 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d", 607 __func__, SOUND_CARD, in->pcm_device_id, in->config.channels); 608 in->pcm = pcm_open(SOUND_CARD, in->pcm_device_id, 609 PCM_IN, &in->config); 610 if (in->pcm && !pcm_is_ready(in->pcm)) { 611 ALOGE("%s: %s", __func__, pcm_get_error(in->pcm)); 612 pcm_close(in->pcm); 613 in->pcm = NULL; 614 ret = -EIO; 615 goto error_open; 616 } 617 ALOGV("%s: exit", __func__); 618 return ret; 619 620error_open: 621 stop_input_stream(in); 622 623error_config: 624 adev->active_input = NULL; 625 ALOGD("%s: exit: status(%d)", __func__, ret); 626 627 return ret; 628} 629 630/* must be called with out->lock locked */ 631static int send_offload_cmd_l(struct stream_out* out, int command) 632{ 633 struct offload_cmd *cmd = (struct offload_cmd *)calloc(1, sizeof(struct offload_cmd)); 634 635 ALOGVV("%s %d", __func__, command); 636 637 cmd->cmd = command; 638 list_add_tail(&out->offload_cmd_list, &cmd->node); 639 pthread_cond_signal(&out->offload_cond); 640 return 0; 641} 642 643/* must be called iwth out->lock locked */ 644static void stop_compressed_output_l(struct stream_out *out) 645{ 646 out->offload_state = OFFLOAD_STATE_IDLE; 647 out->playback_started = 0; 648 out->send_new_metadata = 1; 649 if (out->compr != NULL) { 650 compress_stop(out->compr); 651 while (out->offload_thread_blocked) { 652 pthread_cond_wait(&out->cond, &out->lock); 653 } 654 } 655} 656 657static void *offload_thread_loop(void *context) 658{ 659 struct stream_out *out = (struct stream_out *) context; 660 struct listnode *item; 661 662 out->offload_state = OFFLOAD_STATE_IDLE; 663 out->playback_started = 0; 664 665 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO); 666 set_sched_policy(0, SP_FOREGROUND); 667 prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0); 668 669 ALOGV("%s", __func__); 670 pthread_mutex_lock(&out->lock); 671 for (;;) { 672 struct offload_cmd *cmd = NULL; 673 stream_callback_event_t event; 674 bool send_callback = false; 675 676 ALOGVV("%s offload_cmd_list %d out->offload_state %d", 677 __func__, list_empty(&out->offload_cmd_list), 678 out->offload_state); 679 if (list_empty(&out->offload_cmd_list)) { 680 ALOGV("%s SLEEPING", __func__); 681 pthread_cond_wait(&out->offload_cond, &out->lock); 682 ALOGV("%s RUNNING", __func__); 683 continue; 684 } 685 686 item = list_head(&out->offload_cmd_list); 687 cmd = node_to_item(item, struct offload_cmd, node); 688 list_remove(item); 689 690 ALOGVV("%s STATE %d CMD %d out->compr %p", 691 __func__, out->offload_state, cmd->cmd, out->compr); 692 693 if (cmd->cmd == OFFLOAD_CMD_EXIT) { 694 free(cmd); 695 break; 696 } 697 698 if (out->compr == NULL) { 699 ALOGE("%s: Compress handle is NULL", __func__); 700 pthread_cond_signal(&out->cond); 701 continue; 702 } 703 out->offload_thread_blocked = true; 704 pthread_mutex_unlock(&out->lock); 705 send_callback = false; 706 switch(cmd->cmd) { 707 case OFFLOAD_CMD_WAIT_FOR_BUFFER: 708 compress_wait(out->compr, -1); 709 send_callback = true; 710 event = STREAM_CBK_EVENT_WRITE_READY; 711 break; 712 case OFFLOAD_CMD_PARTIAL_DRAIN: 713 compress_next_track(out->compr); 714 compress_partial_drain(out->compr); 715 send_callback = true; 716 event = STREAM_CBK_EVENT_DRAIN_READY; 717 break; 718 case OFFLOAD_CMD_DRAIN: 719 compress_drain(out->compr); 720 send_callback = true; 721 event = STREAM_CBK_EVENT_DRAIN_READY; 722 break; 723 default: 724 ALOGE("%s unknown command received: %d", __func__, cmd->cmd); 725 break; 726 } 727 pthread_mutex_lock(&out->lock); 728 out->offload_thread_blocked = false; 729 pthread_cond_signal(&out->cond); 730 if (send_callback) { 731 out->offload_callback(event, NULL, out->offload_cookie); 732 } 733 free(cmd); 734 } 735 736 pthread_cond_signal(&out->cond); 737 while (!list_empty(&out->offload_cmd_list)) { 738 item = list_head(&out->offload_cmd_list); 739 list_remove(item); 740 free(node_to_item(item, struct offload_cmd, node)); 741 } 742 pthread_mutex_unlock(&out->lock); 743 744 return NULL; 745} 746 747static int create_offload_callback_thread(struct stream_out *out) 748{ 749 pthread_cond_init(&out->offload_cond, (const pthread_condattr_t *) NULL); 750 list_init(&out->offload_cmd_list); 751 pthread_create(&out->offload_thread, (const pthread_attr_t *) NULL, 752 offload_thread_loop, out); 753 return 0; 754} 755 756static int destroy_offload_callback_thread(struct stream_out *out) 757{ 758 pthread_mutex_lock(&out->lock); 759 stop_compressed_output_l(out); 760 send_offload_cmd_l(out, OFFLOAD_CMD_EXIT); 761 762 pthread_mutex_unlock(&out->lock); 763 pthread_join(out->offload_thread, (void **) NULL); 764 pthread_cond_destroy(&out->offload_cond); 765 766 return 0; 767} 768 769static bool allow_hdmi_channel_config(struct audio_device *adev) 770{ 771 struct listnode *node; 772 struct audio_usecase *usecase; 773 bool ret = true; 774 775 list_for_each(node, &adev->usecase_list) { 776 usecase = node_to_item(node, struct audio_usecase, list); 777 if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 778 /* 779 * If voice call is already existing, do not proceed further to avoid 780 * disabling/enabling both RX and TX devices, CSD calls, etc. 781 * Once the voice call done, the HDMI channels can be configured to 782 * max channels of remaining use cases. 783 */ 784 if (usecase->id == USECASE_VOICE_CALL) { 785 ALOGD("%s: voice call is active, no change in HDMI channels", 786 __func__); 787 ret = false; 788 break; 789 } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) { 790 ALOGD("%s: multi channel playback is active, " 791 "no change in HDMI channels", __func__); 792 ret = false; 793 break; 794 } 795 } 796 } 797 return ret; 798} 799 800static int check_and_set_hdmi_channels(struct audio_device *adev, 801 unsigned int channels) 802{ 803 struct listnode *node; 804 struct audio_usecase *usecase; 805 806 /* Check if change in HDMI channel config is allowed */ 807 if (!allow_hdmi_channel_config(adev)) 808 return 0; 809 810 if (channels == adev->cur_hdmi_channels) { 811 ALOGD("%s: Requested channels are same as current", __func__); 812 return 0; 813 } 814 815 platform_set_hdmi_channels(adev->platform, channels); 816 adev->cur_hdmi_channels = channels; 817 818 /* 819 * Deroute all the playback streams routed to HDMI so that 820 * the back end is deactivated. Note that backend will not 821 * be deactivated if any one stream is connected to it. 822 */ 823 list_for_each(node, &adev->usecase_list) { 824 usecase = node_to_item(node, struct audio_usecase, list); 825 if (usecase->type == PCM_PLAYBACK && 826 usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 827 disable_audio_route(adev, usecase); 828 } 829 } 830 831 /* 832 * Enable all the streams disabled above. Now the HDMI backend 833 * will be activated with new channel configuration 834 */ 835 list_for_each(node, &adev->usecase_list) { 836 usecase = node_to_item(node, struct audio_usecase, list); 837 if (usecase->type == PCM_PLAYBACK && 838 usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 839 enable_audio_route(adev, usecase); 840 } 841 } 842 843 return 0; 844} 845 846static int stop_output_stream(struct stream_out *out) 847{ 848 int i, ret = 0; 849 struct audio_usecase *uc_info; 850 struct audio_device *adev = out->dev; 851 852 ALOGV("%s: enter: usecase(%d: %s)", __func__, 853 out->usecase, use_case_table[out->usecase]); 854 uc_info = get_usecase_from_list(adev, out->usecase); 855 if (uc_info == NULL) { 856 ALOGE("%s: Could not find the usecase (%d) in the list", 857 __func__, out->usecase); 858 return -EINVAL; 859 } 860 861 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD && 862 adev->visualizer_stop_output != NULL) 863 adev->visualizer_stop_output(out->handle); 864 865 /* 1. Get and set stream specific mixer controls */ 866 disable_audio_route(adev, uc_info); 867 868 /* 2. Disable the rx device */ 869 disable_snd_device(adev, uc_info->out_snd_device); 870 871 list_remove(&uc_info->list); 872 free(uc_info); 873 874 /* Must be called after removing the usecase from list */ 875 if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) 876 check_and_set_hdmi_channels(adev, DEFAULT_HDMI_OUT_CHANNELS); 877 878 ALOGV("%s: exit: status(%d)", __func__, ret); 879 return ret; 880} 881 882int start_output_stream(struct stream_out *out) 883{ 884 int ret = 0; 885 struct audio_usecase *uc_info; 886 struct audio_device *adev = out->dev; 887 888 ALOGV("%s: enter: usecase(%d: %s) devices(%#x)", 889 __func__, out->usecase, use_case_table[out->usecase], out->devices); 890 out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK); 891 if (out->pcm_device_id < 0) { 892 ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)", 893 __func__, out->pcm_device_id, out->usecase); 894 ret = -EINVAL; 895 goto error_config; 896 } 897 898 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); 899 uc_info->id = out->usecase; 900 uc_info->type = PCM_PLAYBACK; 901 uc_info->stream.out = out; 902 uc_info->devices = out->devices; 903 uc_info->in_snd_device = SND_DEVICE_NONE; 904 uc_info->out_snd_device = SND_DEVICE_NONE; 905 906 /* This must be called before adding this usecase to the list */ 907 if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) 908 check_and_set_hdmi_channels(adev, out->config.channels); 909 910 list_add_tail(&adev->usecase_list, &uc_info->list); 911 912 select_devices(adev, out->usecase); 913 914 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)", 915 __func__, SOUND_CARD, out->pcm_device_id, out->config.format); 916 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) { 917 out->pcm = pcm_open(SOUND_CARD, out->pcm_device_id, 918 PCM_OUT | PCM_MONOTONIC, &out->config); 919 if (out->pcm && !pcm_is_ready(out->pcm)) { 920 ALOGE("%s: %s", __func__, pcm_get_error(out->pcm)); 921 pcm_close(out->pcm); 922 out->pcm = NULL; 923 ret = -EIO; 924 goto error_open; 925 } 926 } else { 927 out->pcm = NULL; 928 out->compr = compress_open(SOUND_CARD, out->pcm_device_id, 929 COMPRESS_IN, &out->compr_config); 930 if (out->compr && !is_compress_ready(out->compr)) { 931 ALOGE("%s: %s", __func__, compress_get_error(out->compr)); 932 compress_close(out->compr); 933 out->compr = NULL; 934 ret = -EIO; 935 goto error_open; 936 } 937 if (out->offload_callback) 938 compress_nonblock(out->compr, out->non_blocking); 939 940 if (adev->visualizer_start_output != NULL) 941 adev->visualizer_start_output(out->handle); 942 } 943 ALOGV("%s: exit", __func__); 944 return 0; 945error_open: 946 stop_output_stream(out); 947error_config: 948 return ret; 949} 950 951static int stop_voice_call(struct audio_device *adev) 952{ 953 int i, ret = 0; 954 struct audio_usecase *uc_info; 955 956 ALOGV("%s: enter", __func__); 957 adev->in_call = false; 958 959 ret = platform_stop_voice_call(adev->platform); 960 961 /* 1. Close the PCM devices */ 962 if (adev->voice_call_rx) { 963 pcm_close(adev->voice_call_rx); 964 adev->voice_call_rx = NULL; 965 } 966 if (adev->voice_call_tx) { 967 pcm_close(adev->voice_call_tx); 968 adev->voice_call_tx = NULL; 969 } 970 971 uc_info = get_usecase_from_list(adev, USECASE_VOICE_CALL); 972 if (uc_info == NULL) { 973 ALOGE("%s: Could not find the usecase (%d) in the list", 974 __func__, USECASE_VOICE_CALL); 975 return -EINVAL; 976 } 977 978 /* 2. Get and set stream specific mixer controls */ 979 disable_audio_route(adev, uc_info); 980 981 /* 3. Disable the rx and tx devices */ 982 disable_snd_device(adev, uc_info->out_snd_device); 983 disable_snd_device(adev, uc_info->in_snd_device); 984 985 list_remove(&uc_info->list); 986 free(uc_info); 987 988 ALOGV("%s: exit: status(%d)", __func__, ret); 989 return ret; 990} 991 992static int start_voice_call(struct audio_device *adev) 993{ 994 int i, ret = 0; 995 struct audio_usecase *uc_info; 996 int pcm_dev_rx_id, pcm_dev_tx_id; 997 998 ALOGV("%s: enter", __func__); 999 1000 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); 1001 uc_info->id = USECASE_VOICE_CALL; 1002 uc_info->type = VOICE_CALL; 1003 uc_info->stream.out = adev->primary_output; 1004 uc_info->devices = adev->primary_output->devices; 1005 uc_info->in_snd_device = SND_DEVICE_NONE; 1006 uc_info->out_snd_device = SND_DEVICE_NONE; 1007 1008 list_add_tail(&adev->usecase_list, &uc_info->list); 1009 1010 select_devices(adev, USECASE_VOICE_CALL); 1011 1012 pcm_dev_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK); 1013 pcm_dev_tx_id = platform_get_pcm_device_id(uc_info->id, PCM_CAPTURE); 1014 1015 if (pcm_dev_rx_id < 0 || pcm_dev_tx_id < 0) { 1016 ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(%d)", 1017 __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id); 1018 ret = -EIO; 1019 goto error_start_voice; 1020 } 1021 1022 ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)", 1023 __func__, SOUND_CARD, pcm_dev_rx_id); 1024 adev->voice_call_rx = pcm_open(SOUND_CARD, 1025 pcm_dev_rx_id, 1026 PCM_OUT | PCM_MONOTONIC, &pcm_config_voice_call); 1027 if (adev->voice_call_rx && !pcm_is_ready(adev->voice_call_rx)) { 1028 ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_rx)); 1029 ret = -EIO; 1030 goto error_start_voice; 1031 } 1032 1033 ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)", 1034 __func__, SOUND_CARD, pcm_dev_tx_id); 1035 adev->voice_call_tx = pcm_open(SOUND_CARD, 1036 pcm_dev_tx_id, 1037 PCM_IN, &pcm_config_voice_call); 1038 if (adev->voice_call_tx && !pcm_is_ready(adev->voice_call_tx)) { 1039 ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_tx)); 1040 ret = -EIO; 1041 goto error_start_voice; 1042 } 1043 1044 /* set cached volume */ 1045 set_voice_volume_l(adev, adev->voice_volume); 1046 1047 pcm_start(adev->voice_call_rx); 1048 pcm_start(adev->voice_call_tx); 1049 1050 ret = platform_start_voice_call(adev->platform); 1051 if (ret < 0) { 1052 ALOGE("%s: platform_start_voice_call error %d\n", __func__, ret); 1053 goto error_start_voice; 1054 } 1055 adev->in_call = true; 1056 return 0; 1057 1058error_start_voice: 1059 stop_voice_call(adev); 1060 1061 ALOGD("%s: exit: status(%d)", __func__, ret); 1062 return ret; 1063} 1064 1065static int check_input_parameters(uint32_t sample_rate, 1066 audio_format_t format, 1067 int channel_count) 1068{ 1069 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL; 1070 1071 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL; 1072 1073 switch (sample_rate) { 1074 case 8000: 1075 case 11025: 1076 case 12000: 1077 case 16000: 1078 case 22050: 1079 case 24000: 1080 case 32000: 1081 case 44100: 1082 case 48000: 1083 break; 1084 default: 1085 return -EINVAL; 1086 } 1087 1088 return 0; 1089} 1090 1091static size_t get_input_buffer_size(uint32_t sample_rate, 1092 audio_format_t format, 1093 int channel_count) 1094{ 1095 size_t size = 0; 1096 1097 if (check_input_parameters(sample_rate, format, channel_count) != 0) 1098 return 0; 1099 1100 size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000; 1101 /* ToDo: should use frame_size computed based on the format and 1102 channel_count here. */ 1103 size *= sizeof(short) * channel_count; 1104 1105 /* make sure the size is multiple of 64 */ 1106 size += 0x3f; 1107 size &= ~0x3f; 1108 1109 return size; 1110} 1111 1112static uint32_t out_get_sample_rate(const struct audio_stream *stream) 1113{ 1114 struct stream_out *out = (struct stream_out *)stream; 1115 1116 return out->sample_rate; 1117} 1118 1119static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 1120{ 1121 return -ENOSYS; 1122} 1123 1124static size_t out_get_buffer_size(const struct audio_stream *stream) 1125{ 1126 struct stream_out *out = (struct stream_out *)stream; 1127 1128 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1129 return out->compr_config.fragment_size; 1130 } 1131 1132 return out->config.period_size * audio_stream_frame_size(stream); 1133} 1134 1135static uint32_t out_get_channels(const struct audio_stream *stream) 1136{ 1137 struct stream_out *out = (struct stream_out *)stream; 1138 1139 return out->channel_mask; 1140} 1141 1142static audio_format_t out_get_format(const struct audio_stream *stream) 1143{ 1144 struct stream_out *out = (struct stream_out *)stream; 1145 1146 return out->format; 1147} 1148 1149static int out_set_format(struct audio_stream *stream, audio_format_t format) 1150{ 1151 return -ENOSYS; 1152} 1153 1154static int out_standby(struct audio_stream *stream) 1155{ 1156 struct stream_out *out = (struct stream_out *)stream; 1157 struct audio_device *adev = out->dev; 1158 1159 ALOGV("%s: enter: usecase(%d: %s)", __func__, 1160 out->usecase, use_case_table[out->usecase]); 1161 1162 pthread_mutex_lock(&out->lock); 1163 if (!out->standby) { 1164 pthread_mutex_lock(&adev->lock); 1165 out->standby = true; 1166 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1167 if (out->pcm) { 1168 pcm_close(out->pcm); 1169 out->pcm = NULL; 1170 } 1171 } else { 1172 stop_compressed_output_l(out); 1173 out->gapless_mdata.encoder_delay = 0; 1174 out->gapless_mdata.encoder_padding = 0; 1175 if (out->compr != NULL) { 1176 compress_close(out->compr); 1177 out->compr = NULL; 1178 } 1179 } 1180 stop_output_stream(out); 1181 pthread_mutex_unlock(&adev->lock); 1182 } 1183 pthread_mutex_unlock(&out->lock); 1184 ALOGV("%s: exit", __func__); 1185 return 0; 1186} 1187 1188static int out_dump(const struct audio_stream *stream, int fd) 1189{ 1190 return 0; 1191} 1192 1193static int parse_compress_metadata(struct stream_out *out, struct str_parms *parms) 1194{ 1195 int ret = 0; 1196 char value[32]; 1197 struct compr_gapless_mdata tmp_mdata; 1198 1199 if (!out || !parms) { 1200 return -EINVAL; 1201 } 1202 1203 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value)); 1204 if (ret >= 0) { 1205 tmp_mdata.encoder_delay = atoi(value); //whats a good limit check? 1206 } else { 1207 return -EINVAL; 1208 } 1209 1210 ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value)); 1211 if (ret >= 0) { 1212 tmp_mdata.encoder_padding = atoi(value); 1213 } else { 1214 return -EINVAL; 1215 } 1216 1217 out->gapless_mdata = tmp_mdata; 1218 out->send_new_metadata = 1; 1219 ALOGV("%s new encoder delay %u and padding %u", __func__, 1220 out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding); 1221 1222 return 0; 1223} 1224 1225 1226static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 1227{ 1228 struct stream_out *out = (struct stream_out *)stream; 1229 struct audio_device *adev = out->dev; 1230 struct audio_usecase *usecase; 1231 struct listnode *node; 1232 struct str_parms *parms; 1233 char value[32]; 1234 int ret, val = 0; 1235 bool select_new_device = false; 1236 int status = 0; 1237 1238 ALOGD("%s: enter: usecase(%d: %s) kvpairs: %s", 1239 __func__, out->usecase, use_case_table[out->usecase], kvpairs); 1240 parms = str_parms_create_str(kvpairs); 1241 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); 1242 if (ret >= 0) { 1243 val = atoi(value); 1244 pthread_mutex_lock(&out->lock); 1245 pthread_mutex_lock(&adev->lock); 1246 1247 /* 1248 * When HDMI cable is unplugged the music playback is paused and 1249 * the policy manager sends routing=0. But the audioflinger 1250 * continues to write data until standby time (3sec). 1251 * As the HDMI core is turned off, the write gets blocked. 1252 * Avoid this by routing audio to speaker until standby. 1253 */ 1254 if (out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL && 1255 val == AUDIO_DEVICE_NONE) { 1256 val = AUDIO_DEVICE_OUT_SPEAKER; 1257 } 1258 1259 /* 1260 * select_devices() call below switches all the usecases on the same 1261 * backend to the new device. Refer to check_usecases_codec_backend() in 1262 * the select_devices(). But how do we undo this? 1263 * 1264 * For example, music playback is active on headset (deep-buffer usecase) 1265 * and if we go to ringtones and select a ringtone, low-latency usecase 1266 * will be started on headset+speaker. As we can't enable headset+speaker 1267 * and headset devices at the same time, select_devices() switches the music 1268 * playback to headset+speaker while starting low-lateny usecase for ringtone. 1269 * So when the ringtone playback is completed, how do we undo the same? 1270 * 1271 * We are relying on the out_set_parameters() call on deep-buffer output, 1272 * once the ringtone playback is ended. 1273 * NOTE: We should not check if the current devices are same as new devices. 1274 * Because select_devices() must be called to switch back the music 1275 * playback to headset. 1276 */ 1277 if (val != 0) { 1278 out->devices = val; 1279 1280 if (!out->standby) 1281 select_devices(adev, out->usecase); 1282 1283 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->in_call && 1284 (out == adev->primary_output)) { 1285 start_voice_call(adev); 1286 } else if ((adev->mode == AUDIO_MODE_IN_CALL) && adev->in_call && 1287 (out == adev->primary_output)) { 1288 select_devices(adev, USECASE_VOICE_CALL); 1289 } 1290 } 1291 1292 if ((adev->mode == AUDIO_MODE_NORMAL) && adev->in_call && 1293 (out == adev->primary_output)) { 1294 stop_voice_call(adev); 1295 } 1296 1297 pthread_mutex_unlock(&adev->lock); 1298 pthread_mutex_unlock(&out->lock); 1299 } 1300 1301 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1302 parse_compress_metadata(out, parms); 1303 } 1304 1305 str_parms_destroy(parms); 1306 ALOGV("%s: exit: code(%d)", __func__, status); 1307 return status; 1308} 1309 1310static char* out_get_parameters(const struct audio_stream *stream, const char *keys) 1311{ 1312 struct stream_out *out = (struct stream_out *)stream; 1313 struct str_parms *query = str_parms_create_str(keys); 1314 char *str; 1315 char value[256]; 1316 struct str_parms *reply = str_parms_create(); 1317 size_t i, j; 1318 int ret; 1319 bool first = true; 1320 ALOGV("%s: enter: keys - %s", __func__, keys); 1321 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value)); 1322 if (ret >= 0) { 1323 value[0] = '\0'; 1324 i = 0; 1325 while (out->supported_channel_masks[i] != 0) { 1326 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) { 1327 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) { 1328 if (!first) { 1329 strcat(value, "|"); 1330 } 1331 strcat(value, out_channels_name_to_enum_table[j].name); 1332 first = false; 1333 break; 1334 } 1335 } 1336 i++; 1337 } 1338 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value); 1339 str = str_parms_to_str(reply); 1340 } else { 1341 str = strdup(keys); 1342 } 1343 str_parms_destroy(query); 1344 str_parms_destroy(reply); 1345 ALOGV("%s: exit: returns - %s", __func__, str); 1346 return str; 1347} 1348 1349static uint32_t out_get_latency(const struct audio_stream_out *stream) 1350{ 1351 struct stream_out *out = (struct stream_out *)stream; 1352 1353 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) 1354 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY; 1355 1356 return (out->config.period_count * out->config.period_size * 1000) / 1357 (out->config.rate); 1358} 1359 1360static int out_set_volume(struct audio_stream_out *stream, float left, 1361 float right) 1362{ 1363 struct stream_out *out = (struct stream_out *)stream; 1364 int volume[2]; 1365 1366 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) { 1367 /* only take left channel into account: the API is for stereo anyway */ 1368 out->muted = (left == 0.0f); 1369 return 0; 1370 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1371 const char *mixer_ctl_name = "Compress Playback Volume"; 1372 struct audio_device *adev = out->dev; 1373 struct mixer_ctl *ctl; 1374 1375 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 1376 if (!ctl) { 1377 ALOGE("%s: Could not get ctl for mixer cmd - %s", 1378 __func__, mixer_ctl_name); 1379 return -EINVAL; 1380 } 1381 volume[0] = (int)(left * COMPRESS_PLAYBACK_VOLUME_MAX); 1382 volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX); 1383 mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0])); 1384 return 0; 1385 } 1386 1387 return -ENOSYS; 1388} 1389 1390static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, 1391 size_t bytes) 1392{ 1393 struct stream_out *out = (struct stream_out *)stream; 1394 struct audio_device *adev = out->dev; 1395 ssize_t ret = 0; 1396 1397 pthread_mutex_lock(&out->lock); 1398 if (out->standby) { 1399 out->standby = false; 1400 pthread_mutex_lock(&adev->lock); 1401 ret = start_output_stream(out); 1402 pthread_mutex_unlock(&adev->lock); 1403 /* ToDo: If use case is compress offload should return 0 */ 1404 if (ret != 0) { 1405 out->standby = true; 1406 goto exit; 1407 } 1408 } 1409 1410 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1411 ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes); 1412 if (out->send_new_metadata) { 1413 ALOGVV("send new gapless metadata"); 1414 compress_set_gapless_metadata(out->compr, &out->gapless_mdata); 1415 out->send_new_metadata = 0; 1416 } 1417 1418 ret = compress_write(out->compr, buffer, bytes); 1419 ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret); 1420 if (ret >= 0 && ret < (ssize_t)bytes) { 1421 send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER); 1422 } 1423 if (!out->playback_started) { 1424 compress_start(out->compr); 1425 out->playback_started = 1; 1426 out->offload_state = OFFLOAD_STATE_PLAYING; 1427 } 1428 pthread_mutex_unlock(&out->lock); 1429 return ret; 1430 } else { 1431 if (out->pcm) { 1432 if (out->muted) 1433 memset((void *)buffer, 0, bytes); 1434 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes); 1435 ret = pcm_write(out->pcm, (void *)buffer, bytes); 1436 if (ret == 0) 1437 out->written += bytes / (out->config.channels * sizeof(short)); 1438 } 1439 } 1440 1441exit: 1442 pthread_mutex_unlock(&out->lock); 1443 1444 if (ret != 0) { 1445 if (out->pcm) 1446 ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm)); 1447 out_standby(&out->stream.common); 1448 usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) / 1449 out_get_sample_rate(&out->stream.common)); 1450 } 1451 return bytes; 1452} 1453 1454static int out_get_render_position(const struct audio_stream_out *stream, 1455 uint32_t *dsp_frames) 1456{ 1457 struct stream_out *out = (struct stream_out *)stream; 1458 *dsp_frames = 0; 1459 if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) { 1460 pthread_mutex_lock(&out->lock); 1461 if (out->compr != NULL) { 1462 compress_get_tstamp(out->compr, (unsigned long *)dsp_frames, 1463 &out->sample_rate); 1464 ALOGVV("%s rendered frames %d sample_rate %d", 1465 __func__, *dsp_frames, out->sample_rate); 1466 } 1467 pthread_mutex_unlock(&out->lock); 1468 return 0; 1469 } else 1470 return -EINVAL; 1471} 1472 1473static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 1474{ 1475 return 0; 1476} 1477 1478static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 1479{ 1480 return 0; 1481} 1482 1483static int out_get_next_write_timestamp(const struct audio_stream_out *stream, 1484 int64_t *timestamp) 1485{ 1486 return -EINVAL; 1487} 1488 1489static int out_get_presentation_position(const struct audio_stream_out *stream, 1490 uint64_t *frames, struct timespec *timestamp) 1491{ 1492 struct stream_out *out = (struct stream_out *)stream; 1493 int ret = -1; 1494 unsigned long dsp_frames; 1495 1496 pthread_mutex_lock(&out->lock); 1497 1498 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1499 if (out->compr != NULL) { 1500 compress_get_tstamp(out->compr, &dsp_frames, 1501 &out->sample_rate); 1502 ALOGVV("%s rendered frames %ld sample_rate %d", 1503 __func__, dsp_frames, out->sample_rate); 1504 *frames = dsp_frames; 1505 ret = 0; 1506 /* this is the best we can do */ 1507 clock_gettime(CLOCK_MONOTONIC, timestamp); 1508 } 1509 } else { 1510 if (out->pcm) { 1511 size_t avail; 1512 if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) { 1513 size_t kernel_buffer_size = out->config.period_size * out->config.period_count; 1514 int64_t signed_frames = out->written - kernel_buffer_size + avail; 1515 // This adjustment accounts for buffering after app processor. 1516 // It is based on estimated DSP latency per use case, rather than exact. 1517 signed_frames -= 1518 (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL); 1519 1520 // It would be unusual for this value to be negative, but check just in case ... 1521 if (signed_frames >= 0) { 1522 *frames = signed_frames; 1523 ret = 0; 1524 } 1525 } 1526 } 1527 } 1528 1529 pthread_mutex_unlock(&out->lock); 1530 1531 return ret; 1532} 1533 1534static int out_set_callback(struct audio_stream_out *stream, 1535 stream_callback_t callback, void *cookie) 1536{ 1537 struct stream_out *out = (struct stream_out *)stream; 1538 1539 ALOGV("%s", __func__); 1540 pthread_mutex_lock(&out->lock); 1541 out->offload_callback = callback; 1542 out->offload_cookie = cookie; 1543 pthread_mutex_unlock(&out->lock); 1544 return 0; 1545} 1546 1547static int out_pause(struct audio_stream_out* stream) 1548{ 1549 struct stream_out *out = (struct stream_out *)stream; 1550 int status = -ENOSYS; 1551 ALOGV("%s", __func__); 1552 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1553 pthread_mutex_lock(&out->lock); 1554 if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) { 1555 status = compress_pause(out->compr); 1556 out->offload_state = OFFLOAD_STATE_PAUSED; 1557 } 1558 pthread_mutex_unlock(&out->lock); 1559 } 1560 return status; 1561} 1562 1563static int out_resume(struct audio_stream_out* stream) 1564{ 1565 struct stream_out *out = (struct stream_out *)stream; 1566 int status = -ENOSYS; 1567 ALOGV("%s", __func__); 1568 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1569 status = 0; 1570 pthread_mutex_lock(&out->lock); 1571 if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) { 1572 status = compress_resume(out->compr); 1573 out->offload_state = OFFLOAD_STATE_PLAYING; 1574 } 1575 pthread_mutex_unlock(&out->lock); 1576 } 1577 return status; 1578} 1579 1580static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type ) 1581{ 1582 struct stream_out *out = (struct stream_out *)stream; 1583 int status = -ENOSYS; 1584 ALOGV("%s", __func__); 1585 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1586 pthread_mutex_lock(&out->lock); 1587 if (type == AUDIO_DRAIN_EARLY_NOTIFY) 1588 status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN); 1589 else 1590 status = send_offload_cmd_l(out, OFFLOAD_CMD_DRAIN); 1591 pthread_mutex_unlock(&out->lock); 1592 } 1593 return status; 1594} 1595 1596static int out_flush(struct audio_stream_out* stream) 1597{ 1598 struct stream_out *out = (struct stream_out *)stream; 1599 ALOGV("%s", __func__); 1600 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 1601 pthread_mutex_lock(&out->lock); 1602 stop_compressed_output_l(out); 1603 pthread_mutex_unlock(&out->lock); 1604 return 0; 1605 } 1606 return -ENOSYS; 1607} 1608 1609/** audio_stream_in implementation **/ 1610static uint32_t in_get_sample_rate(const struct audio_stream *stream) 1611{ 1612 struct stream_in *in = (struct stream_in *)stream; 1613 1614 return in->config.rate; 1615} 1616 1617static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 1618{ 1619 return -ENOSYS; 1620} 1621 1622static size_t in_get_buffer_size(const struct audio_stream *stream) 1623{ 1624 struct stream_in *in = (struct stream_in *)stream; 1625 1626 return in->config.period_size * audio_stream_frame_size(stream); 1627} 1628 1629static uint32_t in_get_channels(const struct audio_stream *stream) 1630{ 1631 struct stream_in *in = (struct stream_in *)stream; 1632 1633 return in->channel_mask; 1634} 1635 1636static audio_format_t in_get_format(const struct audio_stream *stream) 1637{ 1638 return AUDIO_FORMAT_PCM_16_BIT; 1639} 1640 1641static int in_set_format(struct audio_stream *stream, audio_format_t format) 1642{ 1643 return -ENOSYS; 1644} 1645 1646static int in_standby(struct audio_stream *stream) 1647{ 1648 struct stream_in *in = (struct stream_in *)stream; 1649 struct audio_device *adev = in->dev; 1650 int status = 0; 1651 ALOGV("%s: enter", __func__); 1652 pthread_mutex_lock(&in->lock); 1653 if (!in->standby) { 1654 pthread_mutex_lock(&adev->lock); 1655 in->standby = true; 1656 if (in->pcm) { 1657 pcm_close(in->pcm); 1658 in->pcm = NULL; 1659 } 1660 status = stop_input_stream(in); 1661 pthread_mutex_unlock(&adev->lock); 1662 } 1663 pthread_mutex_unlock(&in->lock); 1664 ALOGV("%s: exit: status(%d)", __func__, status); 1665 return status; 1666} 1667 1668static int in_dump(const struct audio_stream *stream, int fd) 1669{ 1670 return 0; 1671} 1672 1673static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 1674{ 1675 struct stream_in *in = (struct stream_in *)stream; 1676 struct audio_device *adev = in->dev; 1677 struct str_parms *parms; 1678 char *str; 1679 char value[32]; 1680 int ret, val = 0; 1681 int status = 0; 1682 1683 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs); 1684 parms = str_parms_create_str(kvpairs); 1685 1686 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value)); 1687 1688 pthread_mutex_lock(&in->lock); 1689 pthread_mutex_lock(&adev->lock); 1690 if (ret >= 0) { 1691 val = atoi(value); 1692 /* no audio source uses val == 0 */ 1693 if ((in->source != val) && (val != 0)) { 1694 in->source = val; 1695 } 1696 } 1697 1698 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); 1699 1700 if (ret >= 0) { 1701 val = atoi(value); 1702 if ((in->device != val) && (val != 0)) { 1703 in->device = val; 1704 /* If recording is in progress, change the tx device to new device */ 1705 if (!in->standby) 1706 status = select_devices(adev, in->usecase); 1707 } 1708 } 1709 1710 pthread_mutex_unlock(&adev->lock); 1711 pthread_mutex_unlock(&in->lock); 1712 1713 str_parms_destroy(parms); 1714 ALOGV("%s: exit: status(%d)", __func__, status); 1715 return status; 1716} 1717 1718static char* in_get_parameters(const struct audio_stream *stream, 1719 const char *keys) 1720{ 1721 return strdup(""); 1722} 1723 1724static int in_set_gain(struct audio_stream_in *stream, float gain) 1725{ 1726 return 0; 1727} 1728 1729static ssize_t in_read(struct audio_stream_in *stream, void *buffer, 1730 size_t bytes) 1731{ 1732 struct stream_in *in = (struct stream_in *)stream; 1733 struct audio_device *adev = in->dev; 1734 int i, ret = -1; 1735 1736 pthread_mutex_lock(&in->lock); 1737 if (in->standby) { 1738 pthread_mutex_lock(&adev->lock); 1739 ret = start_input_stream(in); 1740 pthread_mutex_unlock(&adev->lock); 1741 if (ret != 0) { 1742 goto exit; 1743 } 1744 in->standby = 0; 1745 } 1746 1747 if (in->pcm) { 1748 ret = pcm_read(in->pcm, buffer, bytes); 1749 } 1750 1751 /* 1752 * Instead of writing zeroes here, we could trust the hardware 1753 * to always provide zeroes when muted. 1754 */ 1755 if (ret == 0 && adev->mic_mute) 1756 memset(buffer, 0, bytes); 1757 1758exit: 1759 pthread_mutex_unlock(&in->lock); 1760 1761 if (ret != 0) { 1762 in_standby(&in->stream.common); 1763 ALOGV("%s: read failed - sleeping for buffer duration", __func__); 1764 usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) / 1765 in_get_sample_rate(&in->stream.common)); 1766 } 1767 return bytes; 1768} 1769 1770static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 1771{ 1772 return 0; 1773} 1774 1775static int add_remove_audio_effect(const struct audio_stream *stream, 1776 effect_handle_t effect, 1777 bool enable) 1778{ 1779 struct stream_in *in = (struct stream_in *)stream; 1780 int status = 0; 1781 effect_descriptor_t desc; 1782 1783 status = (*effect)->get_descriptor(effect, &desc); 1784 if (status != 0) 1785 return status; 1786 1787 pthread_mutex_lock(&in->lock); 1788 pthread_mutex_lock(&in->dev->lock); 1789 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) && 1790 in->enable_aec != enable && 1791 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) { 1792 in->enable_aec = enable; 1793 if (!in->standby) 1794 select_devices(in->dev, in->usecase); 1795 } 1796 pthread_mutex_unlock(&in->dev->lock); 1797 pthread_mutex_unlock(&in->lock); 1798 1799 return 0; 1800} 1801 1802static int in_add_audio_effect(const struct audio_stream *stream, 1803 effect_handle_t effect) 1804{ 1805 ALOGV("%s: effect %p", __func__, effect); 1806 return add_remove_audio_effect(stream, effect, true); 1807} 1808 1809static int in_remove_audio_effect(const struct audio_stream *stream, 1810 effect_handle_t effect) 1811{ 1812 ALOGV("%s: effect %p", __func__, effect); 1813 return add_remove_audio_effect(stream, effect, false); 1814} 1815 1816static int adev_open_output_stream(struct audio_hw_device *dev, 1817 audio_io_handle_t handle, 1818 audio_devices_t devices, 1819 audio_output_flags_t flags, 1820 struct audio_config *config, 1821 struct audio_stream_out **stream_out) 1822{ 1823 struct audio_device *adev = (struct audio_device *)dev; 1824 struct stream_out *out; 1825 int i, ret; 1826 1827 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)", 1828 __func__, config->sample_rate, config->channel_mask, devices, flags); 1829 *stream_out = NULL; 1830 out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); 1831 1832 if (devices == AUDIO_DEVICE_NONE) 1833 devices = AUDIO_DEVICE_OUT_SPEAKER; 1834 1835 out->flags = flags; 1836 out->devices = devices; 1837 out->dev = adev; 1838 out->format = config->format; 1839 out->sample_rate = config->sample_rate; 1840 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; 1841 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; 1842 out->handle = handle; 1843 1844 /* Init use case and pcm_config */ 1845 if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT && 1846 !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && 1847 out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 1848 pthread_mutex_lock(&adev->lock); 1849 ret = read_hdmi_channel_masks(out); 1850 pthread_mutex_unlock(&adev->lock); 1851 if (ret != 0) 1852 goto error_open; 1853 1854 if (config->sample_rate == 0) 1855 config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; 1856 if (config->channel_mask == 0) 1857 config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1; 1858 1859 out->channel_mask = config->channel_mask; 1860 out->sample_rate = config->sample_rate; 1861 out->usecase = USECASE_AUDIO_PLAYBACK_MULTI_CH; 1862 out->config = pcm_config_hdmi_multi; 1863 out->config.rate = config->sample_rate; 1864 out->config.channels = popcount(out->channel_mask); 1865 out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels * 2); 1866 } else if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { 1867 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version || 1868 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) { 1869 ALOGE("%s: Unsupported Offload information", __func__); 1870 ret = -EINVAL; 1871 goto error_open; 1872 } 1873 if (!is_supported_format(config->offload_info.format)) { 1874 ALOGE("%s: Unsupported audio format", __func__); 1875 ret = -EINVAL; 1876 goto error_open; 1877 } 1878 1879 out->compr_config.codec = (struct snd_codec *) 1880 calloc(1, sizeof(struct snd_codec)); 1881 1882 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD; 1883 if (config->offload_info.channel_mask) 1884 out->channel_mask = config->offload_info.channel_mask; 1885 else if (config->channel_mask) 1886 out->channel_mask = config->channel_mask; 1887 out->format = config->offload_info.format; 1888 out->sample_rate = config->offload_info.sample_rate; 1889 1890 out->stream.set_callback = out_set_callback; 1891 out->stream.pause = out_pause; 1892 out->stream.resume = out_resume; 1893 out->stream.drain = out_drain; 1894 out->stream.flush = out_flush; 1895 1896 out->compr_config.codec->id = 1897 get_snd_codec_id(config->offload_info.format); 1898 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE; 1899 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS; 1900 out->compr_config.codec->sample_rate = 1901 compress_get_alsa_rate(config->offload_info.sample_rate); 1902 out->compr_config.codec->bit_rate = 1903 config->offload_info.bit_rate; 1904 out->compr_config.codec->ch_in = 1905 popcount(config->channel_mask); 1906 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in; 1907 1908 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) 1909 out->non_blocking = 1; 1910 1911 out->send_new_metadata = 1; 1912 create_offload_callback_thread(out); 1913 ALOGV("%s: offloaded output offload_info version %04x bit rate %d", 1914 __func__, config->offload_info.version, 1915 config->offload_info.bit_rate); 1916 } else { 1917 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 1918 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER; 1919 out->config = pcm_config_deep_buffer; 1920 } else { 1921 out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY; 1922 out->config = pcm_config_low_latency; 1923 } 1924 if (config->format != audio_format_from_pcm_format(out->config.format)) { 1925 if (k_enable_extended_precision 1926 && pcm_params_format_test(adev->use_case_table[out->usecase], 1927 pcm_format_from_audio_format(config->format))) { 1928 out->config.format = pcm_format_from_audio_format(config->format); 1929 /* out->format already set to config->format */ 1930 } else { 1931 /* deny the externally proposed config format 1932 * and use the one specified in audio_hw layer configuration. 1933 * Note: out->format is returned by out->stream.common.get_format() 1934 * and is used to set config->format in the code several lines below. 1935 */ 1936 out->format = audio_format_from_pcm_format(out->config.format); 1937 } 1938 } 1939 out->sample_rate = out->config.rate; 1940 } 1941 ALOGV("%s: Usecase(%s) config->format %#x out->config.format %#x\n", 1942 __func__, use_case_table[out->usecase], config->format, out->config.format); 1943 1944 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { 1945 if(adev->primary_output == NULL) 1946 adev->primary_output = out; 1947 else { 1948 ALOGE("%s: Primary output is already opened", __func__); 1949 ret = -EEXIST; 1950 goto error_open; 1951 } 1952 } 1953 1954 /* Check if this usecase is already existing */ 1955 pthread_mutex_lock(&adev->lock); 1956 if (get_usecase_from_list(adev, out->usecase) != NULL) { 1957 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase); 1958 pthread_mutex_unlock(&adev->lock); 1959 ret = -EEXIST; 1960 goto error_open; 1961 } 1962 pthread_mutex_unlock(&adev->lock); 1963 1964 out->stream.common.get_sample_rate = out_get_sample_rate; 1965 out->stream.common.set_sample_rate = out_set_sample_rate; 1966 out->stream.common.get_buffer_size = out_get_buffer_size; 1967 out->stream.common.get_channels = out_get_channels; 1968 out->stream.common.get_format = out_get_format; 1969 out->stream.common.set_format = out_set_format; 1970 out->stream.common.standby = out_standby; 1971 out->stream.common.dump = out_dump; 1972 out->stream.common.set_parameters = out_set_parameters; 1973 out->stream.common.get_parameters = out_get_parameters; 1974 out->stream.common.add_audio_effect = out_add_audio_effect; 1975 out->stream.common.remove_audio_effect = out_remove_audio_effect; 1976 out->stream.get_latency = out_get_latency; 1977 out->stream.set_volume = out_set_volume; 1978 out->stream.write = out_write; 1979 out->stream.get_render_position = out_get_render_position; 1980 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 1981 out->stream.get_presentation_position = out_get_presentation_position; 1982 1983 out->standby = 1; 1984 /* out->muted = false; by calloc() */ 1985 /* out->written = 0; by calloc() */ 1986 1987 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL); 1988 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL); 1989 1990 config->format = out->stream.common.get_format(&out->stream.common); 1991 config->channel_mask = out->stream.common.get_channels(&out->stream.common); 1992 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common); 1993 1994 *stream_out = &out->stream; 1995 ALOGV("%s: exit", __func__); 1996 return 0; 1997 1998error_open: 1999 free(out); 2000 *stream_out = NULL; 2001 ALOGD("%s: exit: ret %d", __func__, ret); 2002 return ret; 2003} 2004 2005static void adev_close_output_stream(struct audio_hw_device *dev, 2006 struct audio_stream_out *stream) 2007{ 2008 struct stream_out *out = (struct stream_out *)stream; 2009 struct audio_device *adev = out->dev; 2010 2011 ALOGV("%s: enter", __func__); 2012 out_standby(&stream->common); 2013 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) { 2014 destroy_offload_callback_thread(out); 2015 2016 if (out->compr_config.codec != NULL) 2017 free(out->compr_config.codec); 2018 } 2019 pthread_cond_destroy(&out->cond); 2020 pthread_mutex_destroy(&out->lock); 2021 free(stream); 2022 ALOGV("%s: exit", __func__); 2023} 2024 2025static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 2026{ 2027 struct audio_device *adev = (struct audio_device *)dev; 2028 struct str_parms *parms; 2029 char *str; 2030 char value[32]; 2031 int val; 2032 int ret; 2033 int status = 0; 2034 2035 ALOGV("%s: enter: %s", __func__, kvpairs); 2036 2037 parms = str_parms_create_str(kvpairs); 2038 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); 2039 if (ret >= 0) { 2040 int tty_mode; 2041 2042 if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) 2043 tty_mode = TTY_MODE_OFF; 2044 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) 2045 tty_mode = TTY_MODE_VCO; 2046 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) 2047 tty_mode = TTY_MODE_HCO; 2048 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) 2049 tty_mode = TTY_MODE_FULL; 2050 else 2051 return -EINVAL; 2052 2053 pthread_mutex_lock(&adev->lock); 2054 if (tty_mode != adev->tty_mode) { 2055 adev->tty_mode = tty_mode; 2056 adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode; 2057 if (adev->in_call) 2058 select_devices(adev, USECASE_VOICE_CALL); 2059 } 2060 pthread_mutex_unlock(&adev->lock); 2061 } 2062 2063 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value)); 2064 if (ret >= 0) { 2065 /* When set to false, HAL should disable EC and NS 2066 * But it is currently not supported. 2067 */ 2068 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) 2069 adev->bluetooth_nrec = true; 2070 else 2071 adev->bluetooth_nrec = false; 2072 } 2073 2074 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value)); 2075 if (ret >= 0) { 2076 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) 2077 adev->screen_off = false; 2078 else 2079 adev->screen_off = true; 2080 } 2081 2082 ret = str_parms_get_int(parms, "rotation", &val); 2083 if (ret >= 0) { 2084 bool reverse_speakers = false; 2085 switch(val) { 2086 // FIXME: note that the code below assumes that the speakers are in the correct placement 2087 // relative to the user when the device is rotated 90deg from its default rotation. This 2088 // assumption is device-specific, not platform-specific like this code. 2089 case 270: 2090 reverse_speakers = true; 2091 break; 2092 case 0: 2093 case 90: 2094 case 180: 2095 break; 2096 default: 2097 ALOGE("%s: unexpected rotation of %d", __func__, val); 2098 status = -EINVAL; 2099 } 2100 if (status == 0) { 2101 pthread_mutex_lock(&adev->lock); 2102 if (adev->speaker_lr_swap != reverse_speakers) { 2103 adev->speaker_lr_swap = reverse_speakers; 2104 // only update the selected device if there is active pcm playback 2105 struct audio_usecase *usecase; 2106 struct listnode *node; 2107 list_for_each(node, &adev->usecase_list) { 2108 usecase = node_to_item(node, struct audio_usecase, list); 2109 if (usecase->type == PCM_PLAYBACK) { 2110 select_devices(adev, usecase->id); 2111 break; 2112 } 2113 } 2114 } 2115 pthread_mutex_unlock(&adev->lock); 2116 } 2117 } 2118 2119 str_parms_destroy(parms); 2120 ALOGV("%s: exit with code(%d)", __func__, status); 2121 return status; 2122} 2123 2124static char* adev_get_parameters(const struct audio_hw_device *dev, 2125 const char *keys) 2126{ 2127 return strdup(""); 2128} 2129 2130static int adev_init_check(const struct audio_hw_device *dev) 2131{ 2132 return 0; 2133} 2134 2135/* always called with adev lock held */ 2136static int set_voice_volume_l(struct audio_device *adev, float volume) 2137{ 2138 int vol, err = 0; 2139 2140 if (adev->mode == AUDIO_MODE_IN_CALL) { 2141 if (volume < 0.0) { 2142 volume = 0.0; 2143 } else if (volume > 1.0) { 2144 volume = 1.0; 2145 } 2146 2147 vol = lrint(volume * 100.0); 2148 2149 // Voice volume levels from android are mapped to driver volume levels as follows. 2150 // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 2151 // So adjust the volume to get the correct volume index in driver 2152 vol = 100 - vol; 2153 2154 err = platform_set_voice_volume(adev->platform, vol); 2155 } 2156 return err; 2157} 2158 2159static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 2160{ 2161 int ret; 2162 struct audio_device *adev = (struct audio_device *)dev; 2163 pthread_mutex_lock(&adev->lock); 2164 /* cache volume */ 2165 adev->voice_volume = volume; 2166 ret = set_voice_volume_l(adev, adev->voice_volume); 2167 pthread_mutex_unlock(&adev->lock); 2168 return ret; 2169} 2170 2171static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 2172{ 2173 return -ENOSYS; 2174} 2175 2176static int adev_get_master_volume(struct audio_hw_device *dev, 2177 float *volume) 2178{ 2179 return -ENOSYS; 2180} 2181 2182static int adev_set_master_mute(struct audio_hw_device *dev, bool muted) 2183{ 2184 return -ENOSYS; 2185} 2186 2187static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted) 2188{ 2189 return -ENOSYS; 2190} 2191 2192static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 2193{ 2194 struct audio_device *adev = (struct audio_device *)dev; 2195 2196 pthread_mutex_lock(&adev->lock); 2197 if (adev->mode != mode) { 2198 adev->mode = mode; 2199 } 2200 pthread_mutex_unlock(&adev->lock); 2201 return 0; 2202} 2203 2204static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 2205{ 2206 struct audio_device *adev = (struct audio_device *)dev; 2207 int err = 0; 2208 2209 pthread_mutex_lock(&adev->lock); 2210 adev->mic_mute = state; 2211 2212 err = platform_set_mic_mute(adev->platform, state); 2213 pthread_mutex_unlock(&adev->lock); 2214 return err; 2215} 2216 2217static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 2218{ 2219 struct audio_device *adev = (struct audio_device *)dev; 2220 2221 *state = adev->mic_mute; 2222 2223 return 0; 2224} 2225 2226static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 2227 const struct audio_config *config) 2228{ 2229 int channel_count = popcount(config->channel_mask); 2230 2231 return get_input_buffer_size(config->sample_rate, config->format, channel_count); 2232} 2233 2234static int adev_open_input_stream(struct audio_hw_device *dev, 2235 audio_io_handle_t handle, 2236 audio_devices_t devices, 2237 struct audio_config *config, 2238 struct audio_stream_in **stream_in) 2239{ 2240 struct audio_device *adev = (struct audio_device *)dev; 2241 struct stream_in *in; 2242 int ret, buffer_size, frame_size; 2243 int channel_count = popcount(config->channel_mask); 2244 2245 ALOGV("%s: enter", __func__); 2246 *stream_in = NULL; 2247 if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) 2248 return -EINVAL; 2249 2250 in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); 2251 2252 in->stream.common.get_sample_rate = in_get_sample_rate; 2253 in->stream.common.set_sample_rate = in_set_sample_rate; 2254 in->stream.common.get_buffer_size = in_get_buffer_size; 2255 in->stream.common.get_channels = in_get_channels; 2256 in->stream.common.get_format = in_get_format; 2257 in->stream.common.set_format = in_set_format; 2258 in->stream.common.standby = in_standby; 2259 in->stream.common.dump = in_dump; 2260 in->stream.common.set_parameters = in_set_parameters; 2261 in->stream.common.get_parameters = in_get_parameters; 2262 in->stream.common.add_audio_effect = in_add_audio_effect; 2263 in->stream.common.remove_audio_effect = in_remove_audio_effect; 2264 in->stream.set_gain = in_set_gain; 2265 in->stream.read = in_read; 2266 in->stream.get_input_frames_lost = in_get_input_frames_lost; 2267 2268 in->device = devices; 2269 in->source = AUDIO_SOURCE_DEFAULT; 2270 in->dev = adev; 2271 in->standby = 1; 2272 in->channel_mask = config->channel_mask; 2273 2274 /* Update config params with the requested sample rate and channels */ 2275 in->usecase = USECASE_AUDIO_RECORD; 2276 in->config = pcm_config_audio_capture; 2277 in->config.channels = channel_count; 2278 in->config.rate = config->sample_rate; 2279 2280 frame_size = audio_stream_frame_size((struct audio_stream *)in); 2281 buffer_size = get_input_buffer_size(config->sample_rate, 2282 config->format, 2283 channel_count); 2284 in->config.period_size = buffer_size / frame_size; 2285 2286 *stream_in = &in->stream; 2287 ALOGV("%s: exit", __func__); 2288 return 0; 2289 2290err_open: 2291 free(in); 2292 *stream_in = NULL; 2293 return ret; 2294} 2295 2296static void adev_close_input_stream(struct audio_hw_device *dev, 2297 struct audio_stream_in *stream) 2298{ 2299 ALOGV("%s", __func__); 2300 2301 in_standby(&stream->common); 2302 free(stream); 2303 2304 return; 2305} 2306 2307static int adev_dump(const audio_hw_device_t *device, int fd) 2308{ 2309 return 0; 2310} 2311 2312/* verifies input and output devices and their capabilities. 2313 * 2314 * This verification is required when enabling extended bit-depth or 2315 * sampling rates, as not all qcom products support it. 2316 * 2317 * Suitable for calling only on initialization such as adev_open(). 2318 * It fills the audio_device use_case_table[] array. 2319 * 2320 * Has a side-effect that it needs to configure audio routing / devices 2321 * in order to power up the devices and read the device parameters. 2322 * It does not acquire any hw device lock. Should restore the devices 2323 * back to "normal state" upon completion. 2324 */ 2325static int adev_verify_devices(struct audio_device *adev) 2326{ 2327 /* enumeration is a bit difficult because one really wants to pull 2328 * the use_case, device id, etc from the hidden pcm_device_table[]. 2329 * In this case there are the following use cases and device ids. 2330 * 2331 * [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0}, 2332 * [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {15, 15}, 2333 * [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1}, 2334 * [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {9, 9}, 2335 * [USECASE_AUDIO_RECORD] = {0, 0}, 2336 * [USECASE_AUDIO_RECORD_LOW_LATENCY] = {15, 15}, 2337 * [USECASE_VOICE_CALL] = {2, 2}, 2338 * 2339 * USECASE_AUDIO_PLAYBACK_OFFLOAD, USECASE_AUDIO_PLAYBACK_MULTI_CH omitted. 2340 * USECASE_VOICE_CALL omitted, but possible for either input or output. 2341 */ 2342 2343 /* should be the usecases enabled in adev_open_input_stream() */ 2344 static const int test_in_usecases[] = { 2345 USECASE_AUDIO_RECORD, 2346 USECASE_AUDIO_RECORD_LOW_LATENCY, /* does not appear to be used */ 2347 }; 2348 /* should be the usecases enabled in adev_open_output_stream()*/ 2349 static const int test_out_usecases[] = { 2350 USECASE_AUDIO_PLAYBACK_DEEP_BUFFER, 2351 USECASE_AUDIO_PLAYBACK_LOW_LATENCY, 2352 }; 2353 static const usecase_type_t usecase_type_by_dir[] = { 2354 PCM_PLAYBACK, 2355 PCM_CAPTURE, 2356 }; 2357 static const unsigned flags_by_dir[] = { 2358 PCM_OUT, 2359 PCM_IN, 2360 }; 2361 2362 size_t i; 2363 unsigned dir; 2364 const unsigned card_id = SOUND_CARD; 2365 char info[512]; /* for possible debug info */ 2366 2367 for (dir = 0; dir < 2; ++dir) { 2368 const usecase_type_t usecase_type = usecase_type_by_dir[dir]; 2369 const unsigned flags_dir = flags_by_dir[dir]; 2370 const size_t testsize = 2371 dir ? ARRAY_SIZE(test_in_usecases) : ARRAY_SIZE(test_out_usecases); 2372 const int *testcases = 2373 dir ? test_in_usecases : test_out_usecases; 2374 const audio_devices_t audio_device = 2375 dir ? AUDIO_DEVICE_IN_BUILTIN_MIC : AUDIO_DEVICE_OUT_SPEAKER; 2376 2377 for (i = 0; i < testsize; ++i) { 2378 const audio_usecase_t audio_usecase = testcases[i]; 2379 int device_id; 2380 snd_device_t snd_device; 2381 struct pcm_params **pparams; 2382 struct stream_out out; 2383 struct stream_in in; 2384 struct audio_usecase uc_info; 2385 int retval; 2386 2387 pparams = &adev->use_case_table[audio_usecase]; 2388 pcm_params_free(*pparams); /* can accept null input */ 2389 *pparams = NULL; 2390 2391 /* find the device ID for the use case (signed, for error) */ 2392 device_id = platform_get_pcm_device_id(audio_usecase, usecase_type); 2393 if (device_id < 0) 2394 continue; 2395 2396 /* prepare structures for device probing */ 2397 memset(&uc_info, 0, sizeof(uc_info)); 2398 uc_info.id = audio_usecase; 2399 uc_info.type = usecase_type; 2400 if (dir) { 2401 adev->active_input = ∈ 2402 memset(&in, 0, sizeof(in)); 2403 in.device = audio_device; 2404 in.source = AUDIO_SOURCE_VOICE_COMMUNICATION; 2405 uc_info.stream.in = ∈ 2406 } else { 2407 adev->active_input = NULL; 2408 } 2409 memset(&out, 0, sizeof(out)); 2410 out.devices = audio_device; /* only field needed in select_devices */ 2411 uc_info.stream.out = &out; 2412 uc_info.devices = audio_device; 2413 uc_info.in_snd_device = SND_DEVICE_NONE; 2414 uc_info.out_snd_device = SND_DEVICE_NONE; 2415 list_add_tail(&adev->usecase_list, &uc_info.list); 2416 2417 /* select device - similar to start_(in/out)put_stream() */ 2418 retval = select_devices(adev, audio_usecase); 2419 if (retval >= 0) { 2420 *pparams = pcm_params_get(card_id, device_id, flags_dir); 2421#if LOG_NDEBUG == 0 2422 if (*pparams) { 2423 ALOGV("%s: (%s) card %d device %d", __func__, 2424 dir ? "input" : "output", card_id, device_id); 2425 pcm_params_to_string(*pparams, info, ARRAY_SIZE(info)); 2426 ALOGV(info); /* print parameters */ 2427 } else { 2428 ALOGV("%s: cannot locate card %d device %d", __func__, card_id, device_id); 2429 } 2430#endif 2431 } 2432 2433 /* deselect device - similar to stop_(in/out)put_stream() */ 2434 /* 1. Get and set stream specific mixer controls */ 2435 retval = disable_audio_route(adev, &uc_info); 2436 /* 2. Disable the rx device */ 2437 retval = disable_snd_device(adev, 2438 dir ? uc_info.in_snd_device : uc_info.out_snd_device); 2439 list_remove(&uc_info.list); 2440 } 2441 } 2442 adev->active_input = NULL; /* restore adev state */ 2443 return 0; 2444} 2445 2446static int adev_close(hw_device_t *device) 2447{ 2448 size_t i; 2449 struct audio_device *adev = (struct audio_device *)device; 2450 audio_route_free(adev->audio_route); 2451 free(adev->snd_dev_ref_cnt); 2452 platform_deinit(adev->platform); 2453 for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) { 2454 pcm_params_free(adev->use_case_table[i]); 2455 } 2456 free(device); 2457 return 0; 2458} 2459 2460static int adev_open(const hw_module_t *module, const char *name, 2461 hw_device_t **device) 2462{ 2463 struct audio_device *adev; 2464 int i, ret; 2465 2466 ALOGD("%s: enter", __func__); 2467 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; 2468 2469 adev = calloc(1, sizeof(struct audio_device)); 2470 2471 adev->device.common.tag = HARDWARE_DEVICE_TAG; 2472 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 2473 adev->device.common.module = (struct hw_module_t *)module; 2474 adev->device.common.close = adev_close; 2475 2476 adev->device.init_check = adev_init_check; 2477 adev->device.set_voice_volume = adev_set_voice_volume; 2478 adev->device.set_master_volume = adev_set_master_volume; 2479 adev->device.get_master_volume = adev_get_master_volume; 2480 adev->device.set_master_mute = adev_set_master_mute; 2481 adev->device.get_master_mute = adev_get_master_mute; 2482 adev->device.set_mode = adev_set_mode; 2483 adev->device.set_mic_mute = adev_set_mic_mute; 2484 adev->device.get_mic_mute = adev_get_mic_mute; 2485 adev->device.set_parameters = adev_set_parameters; 2486 adev->device.get_parameters = adev_get_parameters; 2487 adev->device.get_input_buffer_size = adev_get_input_buffer_size; 2488 adev->device.open_output_stream = adev_open_output_stream; 2489 adev->device.close_output_stream = adev_close_output_stream; 2490 adev->device.open_input_stream = adev_open_input_stream; 2491 adev->device.close_input_stream = adev_close_input_stream; 2492 adev->device.dump = adev_dump; 2493 2494 /* Set the default route before the PCM stream is opened */ 2495 pthread_mutex_lock(&adev->lock); 2496 adev->mode = AUDIO_MODE_NORMAL; 2497 adev->active_input = NULL; 2498 adev->primary_output = NULL; 2499 adev->voice_call_rx = NULL; 2500 adev->voice_call_tx = NULL; 2501 adev->voice_volume = 1.0f; 2502 adev->tty_mode = TTY_MODE_OFF; 2503 adev->bluetooth_nrec = true; 2504 adev->in_call = false; 2505 adev->acdb_settings = TTY_MODE_OFF; 2506 /* adev->cur_hdmi_channels = 0; by calloc() */ 2507 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int)); 2508 list_init(&adev->usecase_list); 2509 pthread_mutex_unlock(&adev->lock); 2510 2511 /* Loads platform specific libraries dynamically */ 2512 adev->platform = platform_init(adev); 2513 if (!adev->platform) { 2514 free(adev->snd_dev_ref_cnt); 2515 free(adev); 2516 ALOGE("%s: Failed to init platform data, aborting.", __func__); 2517 *device = NULL; 2518 return -EINVAL; 2519 } 2520 2521 if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) { 2522 adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW); 2523 if (adev->visualizer_lib == NULL) { 2524 ALOGE("%s: DLOPEN failed for %s", __func__, VISUALIZER_LIBRARY_PATH); 2525 } else { 2526 ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH); 2527 adev->visualizer_start_output = 2528 (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib, 2529 "visualizer_hal_start_output"); 2530 adev->visualizer_stop_output = 2531 (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib, 2532 "visualizer_hal_stop_output"); 2533 } 2534 } 2535 2536 *device = &adev->device.common; 2537 if (k_enable_extended_precision) 2538 adev_verify_devices(adev); 2539 2540 ALOGV("%s: exit", __func__); 2541 return 0; 2542} 2543 2544static struct hw_module_methods_t hal_module_methods = { 2545 .open = adev_open, 2546}; 2547 2548struct audio_module HAL_MODULE_INFO_SYM = { 2549 .common = { 2550 .tag = HARDWARE_MODULE_TAG, 2551 .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 2552 .hal_api_version = HARDWARE_HAL_API_VERSION, 2553 .id = AUDIO_HARDWARE_MODULE_ID, 2554 .name = "QCOM Audio HAL", 2555 .author = "Code Aurora Forum", 2556 .methods = &hal_module_methods, 2557 }, 2558}; 2559