Android Audio HAL 接口介绍之 adev_set_parameters()和out_set_parameters()

本文针对在特定使用场景下出现的音频切换问题进行深入探讨。详细分析了adev_set_parameters()和out_set_parameters()两个关键接口的功能及调用流程,旨在为解决插入耳机后音频设备切换异常的问题提供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这几天一直再解决BUG,是两个usease同时存在的场景,插入耳机来实现音频切换的问题。有Recroding+HFP_Call场景,有两个Recording同时存在的场景。当插入有线耳机后,音频设备切换出现问题。由于有HFP Call,所有就涉及了 adev_set_parameters(),HFP的开始和停止都是通过它来控制的。插入耳机后,音频设备切换时通过out_set_parameters()来控制的。之前没怎么太注意,为了解决BUG,详细的跟踪这两个接口的实现和调用流程。

1. adev_set_parameters()

在HAL模块在AudioFlinger里被加载时,在adev_open()中实现和AudioFlinger中set_parameters()关联的。如果应用程序中要调用set_parameters()接口,需要导入AudioManager。他们供应用程序调用的标准接口。这个接口一般被用来控制feature的打开和关闭。我们可以根据自己项目的需求来定制自己的功能控制。在我所经历的项目中,这个接口使用的频率是很高的,如果想控制某些功能的关闭和打开,推荐使用这个接口。具体的代码就不贴在这里,太多了影响阅读效率,可以自己找资源查看。

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};
    adev->device.init_check = adev_init_check;
    adev->device.set_voice_volume = adev_set_voice_volume;
    adev->device.set_master_volume = adev_set_master_volume;
    adev->device.get_master_volume = adev_get_master_volume;
    adev->device.set_master_mute = adev_set_master_mute;
    adev->device.get_master_mute = adev_get_master_mute;
    adev->device.set_mode = adev_set_mode;
    adev->device.set_mic_mute = adev_set_mic_mute;
    adev->device.get_mic_mute = adev_get_mic_mute;
    adev->device.set_parameters = adev_set_parameters;
    adev->device.get_parameters = adev_get_parameters;
    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
    adev->device.open_output_stream = adev_open_output_stream;
    adev->device.close_output_stream = adev_close_output_stream;
    adev->device.open_input_stream = adev_open_input_stream;
    adev->device.close_input_stream = adev_close_input_stream;
    adev->device.dump = adev_dump;

2.out_set_parameters()

这个接口主要是在AudioPolicyManager中被调用,在有新设备被连接后,在AudioPolicyManager会为所有的输出和输入流做设备切换,如果需要做设备切换就调用set_parameters()接口。在Thread.cpp中会调用到audio HAL层去切换音频设备。这接口第三方应用软件是无法使用的。

AudioParameter inputCmd = AudioParameter();
ALOGV("%s: inform input %d of device:%d", __func__,
                      inputDescriptor->mIoHandle, device);
inputCmd.addInt(String8(AudioParameter::keyRouting),device);
                mpClientInterface->setParameters(inputDescriptor->mIoHandle,inputCmd.toString(),delayMs);
AudioParameter param = AudioParameter(String8(address));
free(address);
param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
status = mOutput->stream->common.set_parameters(&mOutput->stream->common,param.toString().string());
*out = (struct stream_out *)calloc(1, sizeof(struct stream_out));*
*out->stream.common.set_parameters = out_set_parameters;*
static inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev) 416 { 417 return reinterpret_cast<const struct legacy_audio_device *>(dev); 418 } 419 420 static int adev_init_check(const struct audio_hw_device *dev) 421 { 422 const struct legacy_audio_device *ladev = to_cladev(dev); 423 424 return ladev->hwif->initCheck(); 425 } 426 427 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 428 { 429 struct legacy_audio_device *ladev = to_ladev(dev); 430 return ladev->hwif->setVoiceVolume(volume); 431 } 432 433 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 434 { 435 struct legacy_audio_device *ladev = to_ladev(dev); 436 return ladev->hwif->setMasterVolume(volume); 437 } 438 439 static int adev_get_master_volume(struct audio_hw_device *dev, float* volume) 440 { 441 struct legacy_audio_device *ladev = to_ladev(dev); 442 return ladev->hwif->getMasterVolume(volume); 443 } 444 445 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 446 { 447 struct legacy_audio_device *ladev = to_ladev(dev); 448 // as this is the legacy API, don't change it to use audio_mode_t instead of int 449 return ladev->hwif->setMode((int) mode); 450 } 451 452 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 453 { 454 struct legacy_audio_device *ladev = to_ladev(dev); 455 return ladev->hwif->setMicMute(state); 456 } 457 458 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 459 { 460 const struct legacy_audio_device *ladev = to_cladev(dev); 461 return ladev->hwif->getMicMute(state); 462 } 463 464 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 465 { 466 struct legacy_audio_device *ladev = to_ladev(dev); 467 return ladev->hwif->setParameters(String8(kvpairs)); 468 } 469 470 static char * adev_get_parameters(const struct audio_hw_device *dev, 471 const char *keys) 472 { 473 const struct legacy_audio_device *ladev = to_cladev(dev); 474 String8 s8; 475 476 s8 = ladev->hwif->getParameters(String8(keys)); 477 return strdup(s8.string()); 478 } 479 480 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 481 const struct audio_config *config) 482 { 483 const struct legacy_audio_device *ladev = to_cladev(dev); 484 return ladev->hwif->getInputBufferSize(config->sample_rate, (int) config->format, 485 audio_channel_count_from_in_mask(config->channel_mask)); 486 } 487 488 static int adev_open_output_stream(struct audio_hw_device *dev, 489 audio_io_handle_t handle, 490 audio_devices_t devices, 491 audio_output_flags_t flags, 492 struct audio_config *config, 493 struct audio_stream_out **stream_out, 494 const char *address __unused) 495 { 496 struct legacy_audio_device *ladev = to_ladev(dev); 497 status_t status; 498 struct legacy_stream_out *out; 499 int ret; 500 501 out = (struct legacy_stream_out *)calloc(1, sizeof(*out)); 502 if (!out) 503 return -ENOMEM; 504 505 devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 506 507 out->legacy_out = ladev->hwif->openOutputStreamWithFlags(devices, flags, 508 (int *) &config->format, 509 &config->channel_mask, 510 &config->sample_rate, &status); 511 if (!out->legacy_out) { 512 ret = status; 513 goto err_open; 514 } 515 516 out->stream.common.get_sample_rate = out_get_sample_rate; 517 out->stream.common.set_sample_rate = out_set_sample_rate; 518 out->stream.common.get_buffer_size = out_get_buffer_size; 519 out->stream.common.get_channels = out_get_channels; 520 out->stream.common.get_format = out_get_format; 521 out->stream.common.set_format = out_set_format; 522 out->stream.common.standby = out_standby; 523 out->stream.common.dump = out_dump; 524 out->stream.common.set_parameters = out_set_parameters; 525 out->stream.common.get_parameters = out_get_parameters; 526 out->stream.common.add_audio_effect = out_add_audio_effect; 527 out->stream.common.remove_audio_effect = out_remove_audio_effect; 528 out->stream.get_latency = out_get_latency; 529 out->stream.set_volume = out_set_volume; 530 out->stream.write = out_write; 531 out->stream.get_render_position = out_get_render_position; 532 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 533 534 *stream_out = &out->stream; 535 return 0; 536 537 err_open: 538 free(out); 539 *stream_out = NULL; 540 return ret; 541 } 542 543 static void adev_close_output_stream(struct audio_hw_device *dev, 544 struct audio_stream_out* stream) 545 { 546 struct legacy_audio_device *ladev = to_ladev(dev); 547 struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream); 548 549 ladev->hwif->closeOutputStream(out->legacy_out); 550 free(out); 551 } 552 553 /** This method creates and opens the audio hardware input stream */ 554 static int adev_open_input_stream(struct audio_hw_device *dev, 555 audio_io_handle_t handle, 556 audio_devices_t devices, 557 struct audio_config *config, 558 struct audio_stream_in **stream_in, 559 audio_input_flags_t flags __unused, 560 const char *address __unused, 561 audio_source_t source __unused) 562 { 563 struct legacy_audio_device *ladev = to_ladev(dev); 564 status_t status; 565 struct legacy_stream_in *in; 566 int ret; 567 568 in = (struct legacy_stream_in *)calloc(1, sizeof(*in)); 569 if (!in) 570 return -ENOMEM; 571 572 devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); 573 574 in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format, 575 &config->channel_mask, &config->sample_rate, 576 &status, (AudioSystem::audio_in_acoustics)0); 577 if (!in->legacy_in) { 578 ret = status; 579 goto err_open; 580 } 581 582 in->stream.common.get_sample_rate = in_get_sample_rate; 583 in->stream.common.set_sample_rate = in_set_sample_rate; 584 in->stream.common.get_buffer_size = in_get_buffer_size; 585 in->stream.common.get_channels = in_get_channels; 586 in->stream.common.get_format = in_get_format; 587 in->stream.common.set_format = in_set_format; 588 in->stream.common.standby = in_standby; 589 in->stream.common.dump = in_dump; 590 in->stream.common.set_parameters = in_set_parameters; 591 in->stream.common.get_parameters = in_get_parameters; 592 in->stream.common.add_audio_effect = in_add_audio_effect; 593 in->stream.common.remove_audio_effect = in_remove_audio_effect; 594 in->stream.set_gain = in_set_gain; 595 in->stream.read = in_read; 596 in->stream.get_input_frames_lost = in_get_input_frames_lost; 597 598 *stream_in = &in->stream; 599 return 0; 600 601 err_open: 602 free(in); 603 *stream_in = NULL; 604 return ret; 605 }
07-15
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值