Audio Device-Android

本文详细介绍了Android系统中音频输入输出设备的种类及定义,包括听筒、扬声器、不同类型的耳机以及蓝牙设备等,并解释了蓝牙的不同连接方式及其应用场景。

       android系统中,音频的输入输出设备的定义。

      (1)输出设备

       DEVICE_OUT_EARPIECE                 : 听筒   

   DEVICE_OUT_SPEAKER                  : 扬声器  

   DEVICE_OUT_WIRED_HEADSET            : 带话筒的耳机  

   DEVICE_OUT_WIRED_HEADPHONE          : 不带话筒的耳机  

   DEVICE_OUT_BLUETOOTH_SCO            : 蓝牙.面向连接(SCO)方式:主要用于话音传输  

   DEVICE_OUT_BLUETOOTH_SCO_HEADSET    : 蓝牙耳机,带话筒  

   DEVICE_OUT_BLUETOOTH_SCO_CARKIT     : 蓝牙车载设备 

   DEVICE_OUT_BLUETOOTH_A2DP           : 蓝牙立体声  

   DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 蓝牙立体声音耳机  

   DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER   : 带话筒的    

   DEVICE_OUT_AUX_DIGITAL              : The audio output device code for S/PDIF or HDMI. S/PDIF的全称是     Sony/Philips Digital Interface Format  

   DEVICE_OUT_ANLG_DOCK_HEADSET        : 通过基座连接的模拟有线耳机  

   DEVICE_OUT_DGTL_DOCK_HEADSET        : 通过基座连接的数字有线耳机 


  (2)输入设备

   DEVICE_IN_COMMUNICATION         : 手机上的话筒  

   DEVICE_IN_AMBIENT               :  

   DEVICE_IN_BUILTIN_MIC           : 蓝牙麦克  

   DEVICE_IN_BLUETOOTH_SCO_HEADSET : 蓝牙耳机上的话筒  

   DEVICE_IN_WIRED_HEADSET         : 有线耳机上的话筒  

   DEVICE_IN_AUX_DIGITAL           :  

   DEVICE_IN_VOICE_CALL            :  

   DEVICE_IN_BACK_MIC              :  

   DEVICE_IN_VT_MIC                :       

   DEVICE_IN_FMRADIO               : FM中的输入.


 (3)关于蓝牙设备:

        蓝牙基带技术支持两种连接方式:
        面向连接(SCO)方式:主要用于话音传输;
        无连接(ACL)方式:主要用于分组数据传输。
        A2DP是Advanced Audio Distribution Profile, 是立体声的.
       AV只管输出,立体的,没有输入; SCO管通讯,有输出也有接收,但是单声道的

  
AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device, 346 audio_policy_dev_state_t state, 347 bool deviceSwitch) 348 { 349 // handle output devices 350 if (audio_is_output_device(device->type())) { 351 SortedVector <audio_io_handle_t> outputs; 352 353 ssize_t index = mAvailableOutputDevices.indexOf(device); 354 355 // save a copy of the opened output descriptors before any output is opened or closed 356 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() 357 mPreviousOutputs = mOutputs; 358 359 bool wasLeUnicastActive = isLeUnicastActive(); 360 361 switch (state) 362 { 363 // handle output device connection 364 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: { 365 if (index >= 0) { 366 ALOGW("%s() device already connected: %s", __func__, device->toString().c_str()); 367 return INVALID_OPERATION; 368 } 369 ALOGV("%s() connecting device %s format %x", 370 __func__, device->toString().c_str(), device->getEncodedFormat()); 371 372 // register new device as available 373 if (mAvailableOutputDevices.add(device) < 0) { 374 return NO_MEMORY; 375 } 376 377 #ifdef OPLUS_BUG_STABILITY 378 if (device->type() == AUDIO_DEVICE_OUT_USB_HEADSET 379 || device->type() == AUDIO_DEVICE_OUT_WIRED_HEADSET 380 || device->type() == AUDIO_DEVICE_OUT_WIRED_HEADPHONE) { 381 for (size_t i = 0; i < mOutputs.size(); i++) { 382 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i); 383 muteMusicStreamForHeadsetDevice(desc); 384 } 385 } 386 #endif /* OPLUS_BUG_STABILITY */ 387 388 // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic 389 // parameters on newly connected devices (instead of opening the outputs...) 390 #ifdef MTK_ONLY_CHANGES 391 // FuBiao@MULTIMEDIA.AUDIOSERVER.FRAMEWORK, 2024/08/19, add for 7711238 ALPS09231691 392 // Fixed the issue of external speaker caused by broadcast device connection failure 393 if (status_t status = broadcastDeviceConnectionState( 394 device, media::DeviceConnectedState::CONNECTED); 395 status != OK && device->isDynamic()) { 396 mAvailableOutputDevices.remove(device); 397 mHwModules.cleanUpForDevice(device); 398 ALOGD("%s() dynamic device %s format %x connection failed", __func__, 399 device->toString().c_str(), device->getEncodedFormat()); 400 return status; 401 } 402 #else /* MTK_ONLY_CHANGES */ 403 if (broadcastDeviceConnectionState( 404 device, media::DeviceConnectedState::CONNECTED) != NO_ERROR) { 405 mAvailableOutputDevices.remove(device); 406 mHwModules.cleanUpForDevice(device); 407 ALOGE("%s() device %s format %x connection failed", __func__, 408 device->toString().c_str(), device->getEncodedFormat()); 409 return INVALID_OPERATION; 410 } 411 #endif /* MTK_ONLY_CHANGES */ 412 413 if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { 414 #if defined(MTK_AUDIO) 415 Mutex::Autolock _l(mDeviceVectorLock); //ALPS04428646 416 #endif 417 if (mAvailableOutputDevices.remove(device) < 0) { 418 MTK_ALOGW("APMERR:mAvailableOutputDevices.remove Fail %s() connecting device %s format %x", 419 __func__, device->toString().c_str(), device->getEncodedFormat()); 420 } 421 422 broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED); 423 424 mHwModules.cleanUpForDevice(device); 425 426 return INVALID_OPERATION; 427 } 428 429 // Populate encapsulation information when a output device is connected. 430 device->setEncapsulationInfoFromHal(mpClientInterface); 431 432 // outputs should never be empty here 433 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():" 434 "checkOutputsForDevice() returned no outputs but status OK"); 435 ALOGV("%s() checkOutputsForDevice() returned %zu outputs", __func__, outputs.size()); 436 437 } break;解释每一行代码
最新发布
11-21
以下是对 `AudioPolicyManager::setDeviceConnectionStateInt` 函数每行代码的详细解释: ```cpp AudioPolicyManager::setDeviceConnectionStateInt( audio_policy_dev_state_t state, const android::media::audio::common::AudioPort& port, audio_format_t encodedFormat) { // 检查传入的 AudioPort 的扩展标签是否为设备类型 if (port.ext.getTag() != AudioPortExt::device) { // 若不是设备类型,返回 BAD_VALUE 表示参数错误 return BAD_VALUE; } // 定义变量用于存储设备类型 audio_devices_t device_type; // 定义变量用于存储设备地址 std::string device_address; // 调用 aidl2legacy_AudioDevice_audio_device 函数将 AIDL 格式的设备信息转换为传统格式 if (status_t status = aidl2legacy_AudioDevice_audio_device( port.ext.get<AudioPortExt::device>().device, &device_type, &device_address); status != OK) { // 若转换失败,返回错误状态 return status; }; // 获取设备名称的 C 风格字符串 const char* device_name = port.name.c_str(); // 打印日志,记录设备类型、状态和编码格式 MTK_ALOGI("[MTK_APM_Route]setDeviceConnectionStateInt() device: 0x%X, state %d, format 0x%X", device_type, state, encodedFormat); // 检查传入的设备类型是否既不是输出设备也不是输入设备 if (!audio_is_output_device(device_type) && !audio_is_input_device(device_type)) { // 若不是输出或输入设备,返回 BAD_VALUE 表示参数错误 return BAD_VALUE; } // 定义一个智能指针用于存储设备描述符 sp<DeviceDescriptor> device; { // 如果定义了 MTK_AUDIO 宏,则对设备向量加锁,避免多线程竞争 #if defined(MTK_AUDIO) Mutex::Autolock _l(mDeviceVectorLock); // ALPS06069819 #endif // 调用 mHwModules 的 getDeviceDescriptor 函数获取设备描述符 device = mHwModules.getDeviceDescriptor( device_type, device_address.c_str(), device_name, encodedFormat, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } // 如果开启了 MTK_BLE_PHONECALL 功能,并且设备类型为 BLE 相关设备 if (FeatureOption::MTK_BLE_PHONECALL && (!Intersection({device_type}, getAudioDeviceOutAllBleSet()).empty() || device_type == AUDIO_DEVICE_IN_BLE_HEADSET)) { // 如果获取到了设备描述符 if (device) { // 调用 setDeviceConnectionStateInt 函数处理设备连接状态 setDeviceConnectionStateInt(device, state); } // 重新获取设备名称的 C 风格字符串 const char* device_name = port.name.c_str(); // 根据设备类型将其转换为对应的总线设备类型 device_type = device_type == AUDIO_DEVICE_IN_BLE_HEADSET ? AUDIO_DEVICE_IN_BUS : AUDIO_DEVICE_OUT_BUS; // 打印日志,记录转换后的设备类型、状态和编码格式 MTK_ALOGI("[MTK_APM_Route]setDeviceConnectionStateInt() device: 0x%X, state %d, format 0x%X", device_type, state, encodedFormat); { // 如果定义了 MTK_AUDIO 宏,则对设备向量加锁,避免多线程竞争 #if defined(MTK_AUDIO) Mutex::Autolock _l(mDeviceVectorLock); // ALPS06069819 #endif // 调用 mHwModules 的 getDeviceDescriptor 函数获取转换后设备类型的设备描述符 device = mHwModules.getDeviceDescriptor( device_type, device_address.c_str(), device_name, encodedFormat, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } } // 如果没有获取到设备描述符 if (device == nullptr) { // 返回 INVALID_OPERATION 表示操作无效 return INVALID_OPERATION; } // 如果定义了 OPLUS_FEATURE_DUALHEADPHONE 宏 #ifdef OPLUS_FEATURE_DUALHEADPHONE // 如果获取到了设备描述符 if(device != nullptr) { // 调用 mAudioPolicyManagerExt 的 oplusSetDeviceConnectionState 函数处理设备连接状态 mAudioPolicyManagerExt->oplusSetDeviceConnectionState((device->getDeviceTypeAddr()).mType, state); } #endif // 如果设备状态为可用状态 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { // 设置设备的额外音频描述符 device->setExtraAudioDescriptors(port.extraAudioDescriptors); } // 如果未定义 OPLUS_FEATURE_AUDIOSERVER_DEBUG 宏 #ifndef OPLUS_FEATURE_AUDIOSERVER_DEBUG // 如果获取到了设备描述符,则调用 setDeviceConnectionStateInt 函数处理设备连接状态,否则返回 INVALID_OPERATION return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION; #else // 定义变量用于存储设备操作状态,初始化为 INVALID_OPERATION status_t devStatus = INVALID_OPERATION; // 如果获取到了设备描述符 if (device != nullptr) { // 打印调试日志 ALOGD("%s() +++ device: %s, state %d, format %x", __func__, device->toString().c_str(), state, device->getEncodedFormat()); // 调用 setDeviceConnectionStateInt 函数处理设备连接状态 devStatus = setDeviceConnectionStateInt(device, state); // 打印调试日志 ALOGD("%s() ---", __func__); } // 返回设备操作状态 return devStatus; #endif } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值