【鸿蒙南向开发】OpenHarmony 源码解析之多媒体子系统(音频框架一)

199 篇文章 8 订阅
198 篇文章 0 订阅

前言

音频采集是多媒体系统中最基础最重要的部分之一,OpenHarmony audio_lite 框架有着丰富的音频采集功能,支持麦克风、电话、摄像机等多种音频输入源设备,支持PCM、AAC_LC、AAC_HE_V1等多种编解码格式,支持闹钟、音乐、铃声等多种音频流类型以及满足不同品质的音频数据需求。

1.2 OpenHarmony架构图

image.png

1.3 架构图

image.png

1.4 文件目录

~/foundation/multimedia/audio_lite$ tree
├── frameworks	# 框架代码
│   ├── audio_capturer.cpp	# 音频采集
│   ├── audio_capturer_impl.cpp
│   ├── audio_capturer_impl.h
│   ├── audio_encoder	# 音频编解码
│   │   ├── audio_encoder.cpp
│   │   └── include
│   │       └── audio_encoder.h
│   └── audio_source	# 音频输入源
│       ├── audio_source.cpp
│       └── include
│           └── audio_source.h
└── interfaces	# 接口
    └── kits	# 对外接口
        └── audio_capturer.h

2 环境准备

2.1 开发环境、编译环境搭建

参考官方文档,参考链接如下:搭建Ubuntu环境(获取源码及编译,Docker方式)

3 音频采集

image.png

3.1 音频信息采集流程

  • 初始化

    通过AudioCapturer调用AudioCapturerImpl中的SetCapturerInfo方法,初始化采集状态,获取适配输入源类型的设备,配置并初始化输入源,编解码等

int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInfo info)
{
    ...

    // 判断采集状态初始化
    if (status_ != INITIALIZED) {
        MEDIA_ERR_LOG("check state:%u failed", status_);
        return ERR_ILLEGAL_STATE;
    }

    // 获取设备
    std::vector<AudioDeviceDesc> devices;
    int32_t ret = audioSource_->EnumDeviceBySourceType(info.inputSource, devices);

    ...

    // 配置输入源参数并初始化
    AudioSourceConfig sourceConfig;
    sourceConfig.deviceId = devices[0].deviceId;
    ...  
    ret = audioSource_->Initialize(sourceConfig);

    ...

    // 配置编解码参数并初始化   
    AudioEncodeConfig encodeConfig;
    encodeConfig.audioFormat = info.audioFormat;
    ...
    ret = audioEncoder_->Initialize(encodeConfig);

    ...

    return SUCCESS;
}

  • 开始音频采集

    调用AudioCapturerImpl中的Record方法检查采集状态,开始采集音频,绑定音频源到当前设备并开始编解码

bool AudioCapturer::AudioCapturerImpl::Record()
{
    ...

    // 开始采集音频源    
    int32_t ret = audioSource_->Start();

    ...

    // 获取当前设备Id
    ret = audioSource_->GetCurrentDeviceId(deviceId);

    ...

    // 绑定音频源到当前设备
    ret = audioEncoder_->BindSource(deviceId);

	...

    // 开始编解码
    ret = audioEncoder_->Start();

    ...

    return true;
}

  • 获取音频数据

    在满足采集状态等的条件下,通过传出参数buffer获取音频数据,如果编解码格式为“PCM”或者是缺省值,则直接获取音频数据,否则进行编解码获取音频数据

int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead)
{
	...

    // 音频帧方式
    if (info_.audioFormat == PCM || info_.audioFormat == AUDIO_DEFAULT) {
        AudioFrame frame;

        ...

        readLen = audioSource_->ReadFrame(frame, isBlockingRead);

		...

    } else {	//音频流方式
        AudioStream stream;

        ...

        readLen = audioEncoder_->ReadStream(stream, isBlockingRead);

      	...

    }
    return readLen;
}

3.2 音频相关结构体

// audio_capturer.h
// 音频采集信息
struct AudioCapturerInfo {
    AudioSourceType inputSource = AUDIO_MIC;	// 音频源类型
    AudioCodecFormat audioFormat = AUDIO_DEFAULT;	// 编解码格式
    int32_t sampleRate = 0;	// 采样率
    int32_t channelCount = 0;	// 通道数
    int32_t bitRate = 0;	// 码率
    AudioStreamType streamType = TYPE_MEDIA;	// 音频流类型
    AudioBitWidth bitWidth = BIT_WIDTH_16;	// 采样位宽
};

// 采集状态
enum State : uint32_t {
    INITIALIZED,	// 初始化
    PREPARED,	// 准备
    RECORDING,	// 采集中
    STOPPED,	// 停止
    RELEASED	// 销毁
};

// audio_encoder.h
// 音频编解码配置
struct AudioEncodeConfig {
    AudioCodecFormat audioFormat;//音频格式
    uint32_t bitRate = 0;//码率
    uint32_t sampleRate = 0;//采样率
    uint32_t channelCount = 0;//通道数量
    AudioBitWidth bitWidth = BIT_WIDTH_16;//采样位宽
};

// audio_source.h
struct AudioSourceConfig {
    uint32_t deviceId;//设备Id
    AudioCodecFormat audioFormat;//音频格式
    int32_t sampleRate = 0;//采样率
    int32_t channelCount = 0;//通道数量
    bool interleaved;
    AudioBitWidth bitWidth = BIT_WIDTH_16;//音频位宽
    AudioStreamType streamUsage;//音频流类型
};

// ~/foundation/multimedia/utils/lite/interfaces/kits/media_info.h
// 音频输入源类型
typedef enum {
    AUDIO_SOURCE_INVALID = -1,	// 无效的音频源
    AUDIO_SOURCE_DEFAULT = 0,	// 默认的音频源
    AUDIO_MIC = 1,	// 麦克风
    AUDIO_VOICE_UPLINK = 2,	// 电话上行
    AUDIO_VOICE_DOWNLINK = 3,	// 电话下行
    AUDIO_VOICE_CALL = 4,	// 电话含上下行
    AUDIO_CAMCORDER = 5,	// 摄像机音频源
    AUDIO_VOICE_RECOGNITION = 6,	// 语音识别
    AUDIO_VOICE_COMMUNICATION = 7,	// 电话通信
    AUDIO_REMOTE_SUBMIX = 8,	// 远程设备输入音频源
    AUDIO_UNPROCESSED = 9,	// 未被处理的音频源
    AUDIO_VOICE_PERFORMANCE = 10,	// 声乐
    AUDIO_ECHO_REFERENCE = 1997,	// 回声
    AUDIO_RADIO_TUNER = 1998,	// 广播调谐器
    AUDIO_HOTWORD = 1999,
    AUDIO_REMOTE_SUBMIX_EXTEND = 10007,	// 扩展的远程设备输入音频源
} AudioSourceType;

// 音频设备描述
typedef struct {
    std::string deviceName;	// 设备名称
    AudioSourceType inputSourceType;	// 音频输入源的类型
    uint32_t deviceId;	// 31-24位:保留位; bits 23-16:模式ID; 15-8:设备ID; 7-0:通道ID  
} AudioDeviceDesc;

// 音频流类型
typedef enum {
    TYPE_DEFAULT = -1,	// 默认类型
    TYPE_MEDIA = 0,	// 媒体
    TYPE_VOICE_COMMUNICATION = 1,	// 语音电话
    TYPE_SYSTEM = 2,	// 系统声音
    TYPE_RING = 3,	// 手机铃声
    TYPE_MUSIC = 4,	// 音乐
    TYPE_ALARM = 5,	// 闹钟
    TYPE_NOTIFICATION = 6,	// 通知声音
    TYPE_BLUETOOTH_SCO = 7,	// 蓝牙同步面向连接
    TYPE_ENFORCED_AUDIBLE = 8,	// 强制提示音
    TYPE_DTMF = 9, // 双音多频
    TYPE_TTS = 10,	// 文本转语音
    TYPE_ACCESSIBILITY = 11,	// 辅助提示音
} AudioStreamType;

// 音频编解码格式
typedef enum {
    AUDIO_DEFAULT    = 0,
    PCM              = 1,
    AAC_LC           = 2,
    AAC_HE_V1        = 3,
    AAC_HE_V2        = 4,
    AAC_LD           = 5,
    AAC_ELD          = 6,
    G711A            = 7,
    G711U            = 8,
    G726             = 9,
    FORMAT_BUTT,
} AudioCodecFormat;

// 采样位宽
typedef enum {
    BIT_WIDTH_8   = 8,
    BIT_WIDTH_16  = 16,
    BIT_WIDTH_24  = 24,
    BIT_WIDTH_32  = 32,
    BIT_WIDTH_BUTT,
} AudioBitWidth;

3.3 音频相关接口

类名接口名描述
AudioCapturerstatic bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount,
AudioCodecFormat audioFormat, size_t &frameCount);
获取最小帧数
AudioCaptureruint64_t GetFrameCount()获取当前条件下所需的帧数
AudioCapturerint32_t SetCapturerInfo(const AudioCapturerInfo info)设置采集参数
AudioCapturerint32_t GetCapturerInfo(AudioCapturerInfo &info)获取采样参数
AudioCapturerbool Start()开始采集
AudioCapturerint32_t Read(uint8_t *buffer, size_t userSize, bool isBlockingRead)读取音频数据
AudioCapturerState GetStatus()获取采集状态
AudioCapturerbool GetAudioTime(Timestamp &timestamp, Timestamp::Timebase base)获取时间戳
AudioCapturerbool Stop()停止采集
AudioCapturerbool Release()销毁
AudioEncoderint32_t Initialize(const AudioEncodeConfig &config)根据给定的配置初始化音频源
AudioEncoderint32_t BindSource(uint32_t deviceId)绑定音频源到给定的设备
AudioEncoderint32_t GetMute(bool &muted)获取当前编码器的静音状态
AudioEncoderint32_t SetMute(bool muted)设置当前编码器的静音状态
AudioEncoderint32_t Start()开始
AudioEncoderint32_t ReadStream(AudioStream &stream, bool isBlockingRead)读取音频流
AudioEncoderint32_t Stop()停止
AudioEncoderint32_t Release()销毁
AudioSourceint32_t EnumDeviceBySourceType(AudioSourceType inputSource,
std::vector &devices)
当前音频源类型支持的设备
AudioSourcestatic bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount,
AudioCodecFormat audioFormat, size_t &frameCount)
获取指定条件下的最小帧数
AudioSourceuint64_t GetFrameCount()获取当前配置条件下的帧数
AudioSourceint32_t Initialize(const AudioSourceConfig &config)根据给定的配置参数初始化
AudioSourceint32_t SetInputDevice(uint32_t deviceId)设置切换设备时输入设备的标识
AudioSourceint32_t GetCurrentDeviceId(uint32_t &deviceId)获取当前设备Id
AudioSourceint32_t Start()开始
AudioSourceint32_t ReadFrame(AudioFrame &frame, bool isBlockingRead)读取源数据帧
AudioSourceint32_t Stop()停止
AudioSourceint32_t Release()销毁

写在最后

●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
●更多鸿蒙最新技术知识点,请移步前往小编:https://gitee.com/

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值