audio HAL

本文深入探讨了Android系统的Audio HAL(硬件抽象层),分析了AudioFlinger.cpp、DevicesFactoryHalHybrid.cpp和DevicesFactoryHalLocal.cpp等关键文件,并详细介绍了硬件层的audio_hw.c实现。通过对这些核心组件的解析,读者可以更好地理解Android音频处理的底层工作原理。

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

AudioFlinger.cpp

AudioFlinger::AudioFlinger()
    : BnAudioFlinger(),
      mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
      mPrimaryHardwareDev(NULL),
      mAudioHwDevs(NULL),
      mHardwareStatus(AUDIO_HW_IDLE),
      mMasterVolume(1.0f),
      mMasterMute(false),
      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
      mIsDeviceTypeKnown(false),
      mGlobalEffectEnableTime(0),
      mSystemReady(false)
{
    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
    for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
        // zero ID has a special meaning, so unavailable
        mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
    }

    getpid_cached = getpid();
    const bool doLog = property_get_bool("ro.test_harness", false);
    if (doLog) {
        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
                MemoryHeapBase::READ_ONLY);
        (void) pthread_once(&sMediaLogOnce, sMediaLogInit);
    }

    // reset battery stats.
    // if the audio service has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    BatteryNotifier::getInstance().noteResetAudio();

    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
    mEffectsFactoryHal = EffectsFactoryHalInterface::create();



frameworks\av\media\libaudiohal\DevicesFactoryHalHybrid.cpp

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "DevicesFactoryHalHybrid"
//#define LOG_NDEBUG 0

#include "DevicesFactoryHalHybrid.h"
#include "DevicesFactoryHalLocal.h"
#ifndef USE_LEGACY_LOCAL_AUDIO_HAL
#include "DevicesFactoryHalHidl.h"
#endif

namespace android {

// static
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
    return new DevicesFactoryHalHybrid();
}

DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
        : mLocalFactory(new DevicesFactoryHalLocal()),
          mHidlFactory(
#ifdef USE_LEGACY_LOCAL_AUDIO_HAL
                  nullptr
#else
                  new DevicesFactoryHalHidl()
#endif
                       ) {
}

DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
}

status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0) {
        return mHidlFactory->openDevice(name, device);
    }
    return mLocalFactory->openDevice(name, device);
}

} // namespace android


frameworks\av\media\libaudiohal\DevicesFactoryHalLocal.cpp

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "DevicesFactoryHalLocal"
//#define LOG_NDEBUG 0

#include <string.h>

#include <hardware/audio.h>
#include <utils/Log.h>

#include "DeviceHalLocal.h"
#include "DevicesFactoryHalLocal.h"

namespace android {

static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
    const hw_module_t *mod;
    int rc;

    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
    if (rc) {
        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
        goto out;
    }
    rc = audio_hw_device_open(mod, dev);
    if (rc) {
        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
        goto out;
    }
    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
        rc = BAD_VALUE;
        audio_hw_device_close(*dev);
        goto out;
    }
    return OK;

out:
    *dev = NULL;
    return rc;
}

status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    audio_hw_device_t *dev;
    status_t rc = load_audio_interface(name, &dev);
    if (rc == OK) {
        *device = new DeviceHalLocal(dev);
    }
    return rc;
}

} // namespace android

hardware\qcom\audio\hal\audio_hw.c

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};


struct audio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = AUDIO_HARDWARE_MODULE_ID,
        .name = "QCOM Audio HAL",
        .author = "The Linux Foundation",
        .methods = &hal_module_methods,
    },
};

### 音频硬件抽象层(Audio HAL)概述 音频硬件抽象层(Audio HAL)是一种用于操作系统中的软件组件,其主要功能是提供一种统一的接口来管理底层音频设备。通过这种设计模式,应用程序开发者无需关心具体的硬件实现细节即可操作音频输入/输出设备。 #### USB Audio HAL 的依赖关系 USB Audio HAL 极大地依赖于 `tinyalsa` 库[^1]。该库是一个轻量级的 ALSA 用户空间工具集,旨在简化高级应用对 ALSA 声音子系统的访问过程。尽管 USB 音频传输基于等时同步(isochronous transfer),但在实际开发过程中,这部分协议的具体处理被 ALSA 实现所封装起来。因此,在 USB Audio HAL 和 `tinyalsa` 中不需要显式考虑这些低层次的 USB 协议细节。 #### Gonk 平台下的 Audio HAL 在 KaiOS 的核心架构——Gonk 中,Audio HAL 是整个平台的重要组成部分之一[^2]。Gonk 使用了一个基于 Android 开源项目(AOSP)定制化的 Linux 内核以及一系列用户态 HAL 组件。除了常见的开源项目如蓝芽支持 (`bluez`) 或者通用串行总线控制 (`libusb`) 外,部分 HAL 功能也继承自 AOSP,比如 GPS 支持、摄像头驱动等等。对于音频方面,则由专门定义好的 HAL 接口负责协调上层服务与下层硬件之间的交互行为。 以下是展示如何初始化并配置一个简单的ALSA PCM流的例子: ```c #include <alsa/asoundlib.h> int main() { snd_pcm_t *handle; int err; /* 打开PCM设备 */ if ((err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(stderr, "无法打开声卡:%s\n", snd_strerror(err)); return -1; } /* 设置硬件参数 */ snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_alloca(&hw_params); snd_pcm_hw_params_any(handle, hw_params); unsigned int rate = 44100; // 采样率设置为44.1kHz snd_pcm_hw_params_set_rate_near(handle, hw_params, &rate, NULL); /* 将修改后的参数应用于当前会话 */ snd_pcm_hw_params(handle, hw_params); /* 关闭句柄 */ snd_pcm_close(handle); return 0; } ``` 此代码片段展示了怎样利用 ALSA API 来建立基本的声音回放路径。它涵盖了从开启默认播放器到调整具体速率等一系列必要步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值