IC:

音频

概述

音频框架是一个完整的音频架构,旨在为应用程序提供不同层次的音频接口。这些接口涉及音频硬件抽象层(Audio HAL)和音频框架(Audio Framework)。

  • 音频硬件抽象层:定义统一的音频硬件接口。它与音频驱动交互以进行音频流或音频设置。

  • 音频框架:提供音频流、音量和其他设置的接口。

    音频框架提供两种架构以满足不同的音频需求。不同的架构有不同的实现,但接口是相同的。

    • 音频混音架构:支持音频录制和音频播放。对于音频播放,该架构提供音频混音功能,并将格式、采样率和声 道转换为统一格式以进行混音。

    • 音频直通架构:支持音频录制和音频播放。该架构没有音频混音功能,同一时刻只允许一个音频播放。

音频混音器概述

音频接口和整体实现如下所示。

../../rst_rtos/4_multimedia/figures/audio_mixer_overview.svg

音频混音架构

整个音频混音架构包括以下子模块:

  • 应用接口

    • RTAudioTrack 提供播放音频流接口。

    • RTAudioRecord 提供录音接口。

    • RTAudioControl 提供控制接口,包括音量,静音控制等。

  • 音频框架接口

    • 音频框架为音频流播放提供音频格式转换、重采样、音量和混音功能。

  • 音频硬件抽象层接口

    • AudioHwManager 管理声卡驱动程序的接口,使得用户获取各个声卡信息,并根据需求打开相应的声卡。

    • AudioHwCard 提供管理声卡功能的接口,包括初始化端口、创建输出流和输入流。

    • AudioHwControl 提供接口给 RTAudioControl 使用,并向音频驱动程序发送音频设置命令。

    • AudioHwStreamOut 从上层获取数据,并将数据流传递给音频驱动程序。

    • AudioHwStreamIn 从音频驱动程序录音数据,并将数据传送到上层接口。

  • 音频驱动

    • AUDIO_SP 提供接口,配置音频 SPORT。

    • AUDIO_CODEC 提供接口,配置音频 CODEC。

音频直通概述

音频接口和整个实现如下所示。

../../rst_rtos/4_multimedia/figures/audio_passthrough_overview.svg

音频直通架构

与音频混音器架构相比,音频直通架构没有音频框架层,其他部分几乎相同。

架构选择

以上部分描述了两种音频架构:混音器和直通。用户可以根据项目要求选择合适的架构。以下是这两种架构的对比:

架构

内存占用情况

代码大小

播放功能

录音功能

基础功能

混音功能

播放延迟

混音架构

相对较多

相对较多

相近

支持

相对较大

相同

直通架构

相对较少

相对较少

相近

不支持

相对较小

相同

  • 在录音实现方面,这两种架构是相同的。两种架构都可以满足用户的录音功能需求。

  • 在播放实现方面,这两种架构是不同的。如果用户需要同时播放两个声音,应选择混音器架构,因为只有混音器架构可以进行混音。

混音器架构占用更多的内存,并且代码体积更大。如果用户希望节省内存和代码体积,并且没有音频混音的需求,应选择直通架构。

音频术语

在本章中,一些常用音频术语的含义列出如下。

术语

简介

PCM

脉冲编码调制(Pulse Code Modulation,PCM)是一种音频信号的数字表示方法。

声道

声道是指在不同位置录音或播放的独立音频信号,因此声道的数量就是声源的数量。

mono

单声道。

stereo

双声道。

bit depth

位深表示在音频信号处理过程中使用的有效位数。

采样深度表示声音的分辨率。值越大,分辨率越高。

采样点

音频采样点是指从连续的模拟音频信号中,按照固定的时间间隔取样得到的离散数据点。

采样率

音频采样率指的是每秒对信号进行采样的帧数。采样率越高,音频品质越好。

帧是一个声音单元,其长度是样本长度乘以通道数量。

增益

音频信号增益控制用于调整信号幅度。

交错的

这是一种音频数据的录制方法。在交错模式下,数据以连续的方式存储,首先存储第一帧的所有通道样本,然后存储第二帧的数据。

延迟

信号通过整个系统时的时间延迟。

overrun

缓冲区过满,使得缓冲区生产者无法写入更多数据。

underrun

缓冲区生产者写入数据的速度太慢,导致当消费者想要消费数据时缓冲区是空的。

xrun

overrun 或者 underrun。

音量

声音强度和响度。

硬件音量

音频 codec 的音量。

软件音量

软件算法中的音量。

重采样

音频采样率转换。

格式转换

音频位深转换。

混音

将多个音频流混音在一起。用户可以听到多个音频流同时播放。

音频 codec

芯片内部的数模转换器(DAC)和模数转换器(ADC)控制器。

音频格式

本节描述了音频框架和音频硬件抽象层(HAL)支持的数据格式。音频框架和音频 HAL 的共同部分将在这里进行描述,而不同的部分将在各自的章节中进行描述。

音频框架和音频硬件抽象层(HAL)都支持交错的流数据。

两声道交错数据示例如下图:

../../rst_rtos/4_multimedia/figures/audio_two_channels_interleaved.svg

四声道交错数据示例如下图:

../../rst_rtos/4_multimedia/figures/audio_four_channels_interleaved.svg

音频架构

播放架构

音频混音器播放架构的框图如下所示:

../../rst_rtos/4_multimedia/figures/audio_playback_mixer_architecture.svg

播放混音架构

音频直通播放架构的框图如下所示:

../../rst_rtos/4_multimedia/figures/audio_playback_passthrough_architecture.svg

播放直通架构

音频播放架构包括以下子模块:

  • 音频框架层(仅针对混音架构)

    • 音频框架负责音频播放声音混音。

    • 在混音之前,所有声音将被转换为一种统一的音频格式,默认是 16 位,44100Hz,2 声道。音频框架中还有音量模块,用于调整不同音频类型的音量,例如,音乐和语音可能有不同的音量。

    • 音频框架支持从 8k 到 96k 的采样率,单声道/立体声,格式包括 8 位、16 位、24 位和 32 位浮点。

  • 硬件抽象层

    • 音频 HAL 从音频框架获取播放数据,并将数据发送到音频驱动程序。

  • 音频驱动

    • 音频驱动程序从音频 HAL 获取播放数据,并将数据发送到音频硬件。

录音架构

音频混音和直通架构具有相同的录音架构。音频录制的框图如下所示:

../../rst_rtos/4_multimedia/figures/audio_record_architecture.svg

录音架构

音频录制架构包含以下子模块:

  • RTAudioRecord: 从音频 HAL 录音,并将数据提供给需要录制数据的音频应用程序。

  • Audio HAL: 从音频驱动程序获取录制数据,并将数据发送到 RTAudioRecord。

  • Audio Driver: 从音频硬件获取录制数据,并将数据发送到音频 HAL。

控制架构

音频混音和直通具有相同的控制架构。音频控制的框图如下所示:

../../rst_rtos/4_multimedia/figures/audio_control_architecture.svg

控制架构

音频控制架构包括以下子模块:

  • RTAudioControl:由应用程序调用,并与 HAL 交互进行音频控制设置。

  • Audio HAL:通过调用驱动程序 API,进行音频控制设置。

  • Audio Driver:控制音频 CODEC 硬件。

RTAudioControl 提供用于设置和获取硬件音量的接口。

#include "audio/audio_control.h"
int32_t RTAudioControl_SetHardwareVolume(float left_volume, float right_volume)

用户将左右声道的音量设置为 0.0 到 1.0,这一设定线性映射到-65.625 到最大分贝。

音频配置

菜单配置

如果用户想要使用音频接口,请选择下列音频配置,并根据 架构选择 选择合适的音频架构。

../../rst_rtos/4_multimedia/figures/audio_menuconfig.svg

音频配置菜单

框架配置

音频配置文件在: {SDK}/component/audio/configs/ameba_audio_mixer_usrcfg.cpp

如果用户想要更改音频 HAL 周期缓冲区大小,或音频混音器的缓冲策略,根据 {SDK}/component/audio/configs/include/ameba_audio_mixer_usrcfg.h 的描述,修改 kPrimaryAudioConfig

配置 out_min_frames_stage 仅支持 RTAUDIO_OUT_MIN_FRAMES_STAGE1RTAUDIO_OUT_MIN_ FRAMES_STAGE2

  • RTAUDIO_OUT_MIN_FRAMES_STAGE1 意味着单次有更多的数据写入音频 HAL。

  • RTAUDIO_OUT_MIN_FRAMES_STAGE2 意味着单次有较少的数据写入音频 HAL。

使用 RTAUDIO_OUT_MIN_FRAMES_STAGE2 配置可以减少音频框架层的延迟,但可能会因为用户送数据速度跟不上,更容易 xrun 引入噪声。用户可根据实验结果选择适合的配置。

HAL 配置

硬件配置文件在: {SDK}/component/soc/amebaxx/usrcfg/include/ameba_audio_hw_usrcfg.h

不同的板子有不同的配置。例如,有些板子需要使用放大器,有些则不需要。不同的板子可能使用不同的引脚来启用放大器;不同放大器的启动时间也有所不同。此外,每个板子使用的数字麦克风 (DMIC)引脚可能不同,数字麦克风的稳定时间也可能不同。所有这些信息都需要在配置文件中进行配置。

文件 ameba_audio_hw_usrcfg.h 当中有各个配置的描述,请根据描述进行配置。

音频接口

音频组件提供了三层接口:

接口层级

介绍

音频驱动接口

提供音频硬件接口

音频硬件抽象层接口

隔离操作系统和硬件设备,使得应用程序可以通过统一的接口访问音频硬件资源

音频框架层接口

用户层接口,用来播放音频流,录制音频流,控制音频音量等

接口层如下所示:

../../rst_rtos/4_multimedia/figures/audio_interfaces.svg

音频接口

驱动接口

  • SPORT 接口,请参考: {SDK}/component/soc/amebadplus/fwlib/include/ameba_sport.h

  • CODEC 接口,请参考: {SDK}/component/soc/amebadplus/fwlib/include/ameba_audio.h

I2S PLL APIs

有两种方式来生成 I2S PLL:

  • 如果系统时钟是 98.304M 或 45.1584M 的整数倍,可以在 SocClk_Info 数组中添加时钟,然后在 bootloader_km4.c 中修改 SocClk_Info 数组中的索引。如果想要高品质的音频,请选择这种做法。

  • 如果系统时钟不是 98.304M 或 45.1584M 的整数倍,此时可以自动获取 98.304M 或 45.1584M。

I2S PLL 接口使用流程如下图所示:

../../rst_rtos/4_multimedia/figures/audio_i2s_pll_interfaces.svg

HAL 接口

音频 HAL 提供 AudioHwStreamOut/AudioHwStreamIn/AudioHwControl 接口来控制音频硬件。接口位于 {SDK}/component/audio/interfaces/hardware/audio。这些接口中包含具体描述,使用前请阅读。

  • AudioHwStreamOut: 从上层接收 PCM 数据,通过音频驱动写入数据以将 PCM 数据发送到硬件,并提供关于音频输出硬件驱动的信息。

  • AudioHwStreamIn: 通过音频驱动接收 PCM 数据并发送到上层。

  • AudioHwControl: 接收来自上层的控制调用,并将控制信息设置给驱动程序。

AudioHwStreamOut/AudioHwStreamIn 由 AudioHwCard 接口管理,负责创建/销毁 AudioHwStreamOut/AudioHwStreamIn 实例。

AudioHwCard 是用于处理音频流的声卡,包含一组端口和设备。

  • Port – 声卡的输入/输出流

  • Device – 声卡的输入/输出设备

AudioHwCard 示例如下图所示:

../../rst_rtos/4_multimedia/figures/audio_hal_architecture.svg

AudioHwManager 管理系统中所有的 AudioHwCard,并根据给定的音频卡描述符打开指定的声卡驱动。

使用 AudioHwStreamOut

AudioHwStreamOut 的使用样例位于 {SDK}/component/example/audio/audio_hal_render

使用音频 HAL 接口播放音频原始数据(PCM 格式)的步骤如下:

  1. 使用 CreateAudioHwManager() 获取 AudioHwManager 句柄

    struct AudioHwManager *audio_manager = CreateAudioHwManager();
    
  2. 使用 GetCards() 获取声卡描述符

    int32_t cards_size = audio_manager->GetCardsCount(audio_manager);
    struct AudioHwCardDescriptor *card_descs = audio_manager->GetCards(audio_manager);
    
  3. 选择一个特定的声卡来播放音频(当前音频管理器仅支持主音频卡)

    struct AudioHwCardDescriptor *audio_card_desc;
    for (int32_t index = 0; index < cards_size; index++) {
       struct AudioHwCardDescriptor *desc = &card_descs[index];
       for (uint32_t port = 0; (desc != NULL && port < desc->port_num); port++) {
          printf("check for audio port \n");
          if (desc->ports[port].role == AUDIO_HW_PORT_ROLE_OUT &&
             (audio_card = audio_manager->OpenCard(audio_manager, desc))) {
             audio_port = desc->ports[port];
             audio_card_desc = desc;
             break;
          }
       }
    }
    
  4. 根据采样率、声道、格式和 AudioHwPathDescriptor,创建 AudioHwConfig,然后使用 CreateStreamOut() 来基于选中的声卡创建 AudioHwStreamOut

    struct AudioHwConfig audio_config;
    audio_config.sample_rate = 48000;
    audio_config.channel_count = 2;
    audio_config.format = AUDIO_HW_FORMAT_PCM_16_BIT;
    struct AudioHwPathDescriptor path_desc;
    path_desc.port_index = audio_port.port_index;
    path_desc.devices = AUDIO_HW_DEVICE_OUT_SPEAKER;
    path_desc.flags = AUDIO_HW_INPUT_FLAG_NONE;
    audio_stream_out = audio_card->CreateStreamOut(audio_card, &path_desc, &audio_config);
    
  5. 重复写入 PCM 数据到 AudioHwStreamOut。用户可以自定义写入的 size 大小,但需要确保 size/frame_size 是整数

    int32_t bytes = audio_stream_out->Write(audio_stream_out, buffer, size, true);
    
  6. 使用 DestroyStreamOut() 来关闭 AudioHwStreamOut,以结束播放

    audio_card->DestroyStreamOut(audio_card, audio_stream_out);
    
  7. 使用 CloseCard() 来销毁 AudioHwCard,并使用 DestoryAudioHwManager 来释放 AudioHwManager 句柄:

    audio_manager->CloseCard(audio_manager, audio_card, audio_card_desc);
    DestoryAudioHwManager(audio_manager);
    

使用 AudioHwStreamIn

AudioHwStreamOut 的使用样例位于 {SDK}/component/example/audio/audio_hal_capture

使用音频 HAL 接口录制音频原始数据的步骤如下:

  1. 使用 CreateAudioHwManager() 来获取 AudioHwManager 实例

    struct AudioHwManager *audio_manager = CreateAudioHwManager();
    
  2. 使用 GetCards() 来获取所有声卡描述符

    int32_t cards_size = audio_manager->GetCardsCount(audio_manager);
    struct AudioHwCardDescriptor *card_descs = audio_manager->GetCards(audio_manager);
    
  3. 选择特定的录音卡进行录音(当前音频管理器仅支持主音频卡)

    struct AudioHwCardDescriptor *audio_card_in_desc = NULL;
    for (int32_t index = 0; index < cards_size; index++) {
       struct AudioHwCardDescriptor *desc = &card_descs[index];
       for (uint32_t port = 0; (desc != NULL && port < desc->port_num); port++) {
          if (desc->ports[port].role == AUDIO_HW_PORT_ROLE_IN &&
             (audio_card_in = audio_manager->OpenCard(audio_manager, desc))) {
             audio_port_in = desc->ports[port];
             audio_card_in_desc = desc;
             break;
          }
       }
    }
    
  4. 根据采样率、通道、格式和 AudioHwPathDescriptor 创建 AudioHwConfig,然后使用 CreateStreamIn() 来基于声卡创建 AudioHwStreamIn

    struct AudioHwConfig audio_config;
    audio_config.sample_rate = 48000;
    audio_config.channel_count = 2;
    audio_config.format = AUDIO_HW_FORMAT_PCM_16_BIT;
    struct AudioHwPathDescriptor path_desc_in;
    path_desc_in.port_index = audio_port_in.port_index;
    path_desc_in.devices = AUDIO_HW_DEVICE_IN_MIC;
    path_desc_in.flags = AUDIO_HW_INPUT_FLAG_NONE;
    audio_stream_in = audio_card_in->CreateStreamIn(audio_card_in, &path_desc_in, &audio_config);
    
  5. 重复从 AudioHwStreamIn 中读取 PCM 数据。此大小可以由用户定义,但需要确保 size/frame_size 是整数

    audio_stream_in->Read(audio_stream_in, buffer, size);
    
  6. 使用 DestroyStreamIn() 来关闭 AudioHwStreamIn,以结束录音

    audio_card_in->DestroyStreamIn(audio_card_in, audio_stream_in);
    
  7. 使用 CloseCard() 来释放 AudioHwCard,并调用函数 DestoryAudioHwManager() 释放 AudioHwManager 句柄

    audio_manager->CloseCard(audio_manager, audio_card_in, audio_card_in_desc);
    DestoryAudioHwManager(audio_manager);
    

使用 AudioHwControl

以下示例展示了如何使用音频 HAL 接口来控制音频 CODEC。

AudioHwControl 始终是线程安全的,调用非常方便。要使用 AudioHwControl,函数调用的第一个参数应该始终是 GetAudioHwControl()

以 PLL clock 设定为例:

GetAudioHwControl()->AdjustPLLClock(GetAudioHwControl(), rate, ppm, action);

音频框架接口

音频流接口

音频流接口包括 RTAudioTrack 和 RTAudioRecord 接口。这些接口位于: {SDK}/component/audio/interfaces/audio. 这些接口中有具体的说明,请在使用前阅读。

  • RTAudioTrack: 初始化框架中播放数据流的格式,从应用程序接收 PCM 数据,并将数据写入音频框架(混音器)或音频 HAL(直通)。

  • RTAudioRecord: 初始化框架中录制数据流的格式,从音频 HAL 接收 PCM 数据,并将数据发送到应用程序。

使用 RTAudioTrack

RTAudioTrack RTAudioTrack 支持播放多种常见的音频原始格式类型,以便音频可以轻松集成到应用程序中。

音频框架具有以下音频播放流类型。应用程序可以使用这些类型来初始化 RTAudioTrack。框架获取流类型并根据这些类型进行音量混合。

  • RTAUDIO_CATEGORY_MEDIA - 如果应用程序想要播放音乐,那么其类型为 RTAUDIO_CATEGORY_MEDIA,可以使用此类型来初始化 RTAudioTrack. 音频框架会识别它的类型,并将其与媒体音量混合。

  • RTAUDIO_CATEGORY_COMMUNICATION - 如果应用程序想要进行电话通话并输出通话声音,声音的类型应为 RTAUDIO_CATEGORY_COMMUNICATION

  • RTAUDIO_CATEGORY_SPEECH - 输出语音声音。

  • RTAUDIO_CATEGORY_BEEP - 如果声音是按键音或其他哔声,则其类型为 RTAUDIO_CATEGORY_BEEP

RTAudioTrack 的测试 demo 在:{SDK}/component/example/audio/audio_track

播放音频原始数据的示例如下:

  1. 在使用 RTAudioTrack 之前,RTAudioService 需要先进行初始化

    RTAudioService_Init();
    
  2. 创建 RTAudioTrack 来播放音频

    struct RTAudioTrack* audio_track = RTAudioTrack_Create();
    

    应用程序可以使用音频配置 API 提供有关特定音频播放源的详细音频信息,包括流类型(播放源类型)、格式、声道数、采样率和 RTAudioTrack 环形缓冲区大小。语法如下:

    typedef struct {
    uint32_t category_type;
    uint32_t sample_rate;
    uint32_t channel_count;
    uint32_t format;
    uint32_t buffer_bytes;
    } RTAudioTrackConfig;
    

    其中:

    category_type:

    定义播放数据源的流类型。

    sample_rate:

    播放源原始数据的采样率。

    channel_count:

    播放源原始数据的声道数。

    format:

    播放源原始数据的位深。

    buffer_bytes:

    RTAudioTrack 的环形缓冲区大小,以避免 xrun。

    备注

    RTAudioTrackConfig 中的 buffer_bytes 非常重要。缓冲区大小应始终大于音频框架计算出的最小缓冲区大小,否则将会发生溢出。

  3. 使用该接口获取最小的 RTAudioTrack 缓冲区字节数,并以此作为参考来定义 RTAudioTrack 的缓冲区大小

    例如,您可以将最小缓冲区大小*4 作为缓冲区大小。 您使用的缓冲区越大,播放就会越流畅,但可能会导致较高的延迟。缓冲区大小由您自行决定。

    int track_buf_size = RTAudioTrack_GetMinBufferBytes(audio_track, type, rate, format, channels) * 4;
    
  4. 使用此缓冲区大小和其他音频参数来创建 RTAudioTrackConfig 对象,示例如下:

    RTAudioTrackConfig track_config;
    track_config.category_type = RTAUDIO_CATEGORY_MEDIA;
    track_config.sample_rate = rate;
    track_config.format = format;
    track_config.buffer_bytes = track_buf_size;
    track_config.channel_count = channel_count;
    

    通过 RTAudioTrackConfig 对象,我们可以初始化 RTAudioTrack。在此步骤中,将根据缓冲区字节数创建一个环形缓冲区。

    RTAudioTrack_Init(audio_track, &track_config);
    
  5. 当所有准备工作完成后,启动 RTAudioTrack 并检查是否成功启动

    if(RTAudioTrack_Start(audio_track) != 0){
       //track start fail
       return;
    }
    

    RTAudioTrack 的默认音量是最大值 1.0,您可以使用以下 API 调整音量。

    RTAudioTrack_SetVolume(audio_track, 1.0, 1.0);
    

    备注

    • 在混音器架构中,此 API 设置当前 audio_track 的软件音量。

    • 在直通架构中,此 API 不支持。

  6. 将音频数据写入框架。用户可以自定义 write_size,但需要确保 write_size/frame_size 为整数

    RTAudioTrack_Write(audio_track, buffer, write_size, true);
    
  7. 如果用户想要暂停并停止写入数据,可以调用以下 API 来通知框架执行暂停操作

    RTAudioTrack_Pause(audio_track);
    RTAudioTrack_Flush(audio_track);
    
  8. 如果用户想要停止播放音频,可以停止写入数据,然后调用 API RTAudioTrack_Stop()

    RTAudioTrack_Stop(audio_track);
    
  9. 在 audio_track 指针无用时将其删除

    RTAudioTrack_Destroy(audio_track);
    
使用 RTAudioRecord

RTAudioRecord 支持多种常见的音频原始格式类型,因此可以轻松地将录音集成到应用程序中。

RTAudioRecord 支持以下音频输入源:

  • RTDEVICE_IN_MIC:如果应用程序想要从麦克风录音,请选择此输入源。

  • RTDEVICE_IN_I2S:如果应用程序想要从 I2S 录音,请选择此输入源。

RTAudioRecord 测试样例位于 {SDK}/component/example/audio/audio_record

录制音频原始数据的示例如下:

  1. 创建 RTAudioRecord

    struct RTAudioRecord *audio_record = RTAudioRecord_Create();
    
  2. 应用程序可以使用音频配置 API 来提供有关特定音频记录源的详细音频信息,包括记录设备源、格式、声道数量和采样率

    语法如下:

    typedef struct {
    uint32_t sample_rate;
    uint32_t channel_count;
    uint32_t format;
    uint32_t device;
    uint32_t buffer_bytes;
    } RTAudioRecordConfig;
    

    其中,

    sample_rate:

    原始数据的采样率。

    channel_count:

    原始数据的声道数。

    format:

    原始数据的位深。

    device:

    音频输入设备。

    buffer_bytes:

    框架中的音频缓冲字节数。设置为 0 使用默认值。用户也可以设置其他值,较大的 buffer_bytes 意味着较大的延迟。

    创建 RTAudioRecord 的 RTAudioRecordConfig 对象的示例如下:

    RTAudioRecordConfig record_config;
    record_config.sample_rate = rate;
    record_config.format = RTAUDIO_FORMAT_PCM_16_BIT;
    record_config.channel_count = channels;
    record_config.device = RTDEVICE_IN_MIC;
    record_config.buffer_bytes = 0;
    
  3. 创建 RTAudioRecordConfig 对象后,初始化 RTAudioRecord。在此步骤中,将根据音频输入设备源打开音频 HAL 的 AudioHwCard

    RTAudioRecord_Init(audio_record, &record_config);
    
  4. 当所有准备工作完成后,开始音频录制

    RTAudioRecord_Start(audio_record);
    
  5. 读取音频麦克风数据。读取的大小可以由用户定义,但需要确保 size/frame_size 是整数

    RTAudioRecord_Read(audio_record, buffer, size, true);
    
  6. 当录音结束时,停止录音

    RTAudioRecord_Stop(audio_record);
    
  7. 当 audio_record 不再使用时,销毁它以避免内存泄漏

    RTAudioRecord_Destroy(audio_record);
    

音频控制接口

音频控制接口包括 RTAudioControl 接口,用于与音频控制 HAL 交互。

RTAudioControl 提供了用于设置和获取硬件音量、设置输出设备等的接口。这些接口位于 SDK/component/audio/interfaces/audio/audio_control.h。这些接口有具体的描述,在使用前请阅读。

使用 RTAudioControl

要使用 RTAudioControl,请调用 RTAudioControl 设置 DAC 的音频硬件音量。

RTAudioControl_SetHardwareVolume(0.5, 0.5);

对于播放和录音情况,大多数 RTAudioControl API 可以随时随地调用,它们可以直接工作。只有 RTAudioControl_SetPlaybackDevice() 混音架构中需要在函数 RTAudioService_Init() 之前调用,直通架构需要在 RTAudioTrack_Start() 函数之前调用。