【Android 高性能音频】AAudio 音频流 样本缓冲 相关配置 ( 通道数 | 样本格式 | 帧缓冲 | 采样率 | 每帧样本数 == 通道数 )



I . AAudio 音频流创建流程


红色标题是本博客讲解的内容 , 黑色是前几篇讲过的内容 ;

使用 AAudio 音频库 , 首先需要导入 AAudio.h 头文件 ;

#include <AAudio.h>

创建 AAudio 音频流 , 需要先创建 AAudio 音频流构建器 , 然后在通过该构建器创建音频流 ;

    //创建构建器 , AAudio 音频流通过该构建器创建
    //声明 AAudio 音频流构建器 指针
    AAudioStreamBuilder *builder = nullptr;
    //创建 AAudio 音频流构建器 , 注意传入二维指针
    aaudio_result_t result = AAudio_createStreamBuilder(&builder);

设置音频设备 ID ;

    // 设置音频流设备 ID
    AAudioStreamBuilder_setDeviceId(builder, playbackDeviceId_);

设置音频流方向 ;

    // 设置音频流方向
    AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_OUTPUT);

设置音频设备共享模式 ;

    // 设置共享模式 , 独占模式性能更高 , 延迟更低 ; 如果 该音频设备正在被使用 , 设置失败会自动设置成 共享模式
    AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);

设置性能模式 ;

    // 设置性能模式
    AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);

设置 AAudio 音频流通道数 :

    // 设置通道个数
    AAudioStreamBuilder_setChannelCount(builder, sampleChannels_);

设置 AAudio 音频流样本格式 :

    // 设置音频格式
    AAudioStreamBuilder_setFormat(builder, sampleFormat_);

设置 AAudio 音频流缓冲区大小 : 这里的缓冲区是播放器的缓冲区 , 单位是帧 , 每帧的采样数就是通道数 , 单声道 每帧 1 个采样, 双声道立体声每帧 2 个采样 , 分别对应左右声道的采样 ;

    // 设置每帧的缓冲区大小 , 可以通过该设置达到尽可能低的延迟
    AAudioStream_setBufferSizeInFrames(playStream_, framesPerBurst_);

下面会着重对上面的流程细节进行详细解析 ;
每个方法的参数 , 原理 , 返回值 等细节都会讲解到 ;



II . AAudio 音频流构建器 设置 通道数 AAudioStreamBuilder_setChannelCount


1 . AAudio 音频流通道数设置 :

  • ① 函数原型 :
AAUDIO_API void AAudioStreamBuilder_setChannelCount(
  AAudioStreamBuilder *builder,
  int32_t channelCount
)
  • ② 函数作用 : 设置音频流的通道数 , 设置 1 代表 单声道 , 设置 2 代表 立体声 ;
  • ③ 代码示例 :
    // 设置通道个数
    AAudioStreamBuilder_setChannelCount(builder, sampleChannels_);

2 . 默认处理 :

  • ① 默认值 : 如果没有调用该函数设置通道数 , 默认为 AAUDIO_UNSPECIFIED ;

  • ② 默认情况处理 : 如果通道数未指定 , 打开流时系统自动选择一个最佳通道数 , 不同设备可能有不同的通道数 ;

3. 指定通道值情况处理 : 如果指定了通道数 , 那么打开流时会使用该通道数 ; 如果通道数与设备不匹配 , 那么 AAudio 音频流打开时会报错 ;



III . AAudio 音频流构建器 设置音频格式 AAudioStreamBuilder_setFormat


1 . AAudio 音频流格式设置 :

  • ① 函数原型 :
AAUDIO_API void AAudioStreamBuilder_setFormat(
  AAudioStreamBuilder *builder,
  aaudio_format_t format
)
  • ② 函数作用 : 设置 AAudio 音频流的样本数据格式 ;
  • ③ 参数 AAudioStreamBuilder *builder : AAudio 音频流构建器 ;
  • ④ 参数 aaudio_format_t format : 音频格式 , 一般是 AAUDIO_FORMAT_PCM_FLOAT ( 浮点型采样格式 ) 或 AAUDIO_FORMAT_PCM_I16 ( 每个采样 16 位 ) ;
  • ⑤ 代码示例 :
    // 设置音频格式
    AAudioStreamBuilder_setFormat(builder, sampleFormat_);

2 . 默认设置 :

  • ① 默认值 : 如果没有设置音频流样本格式 , 那么会默认设置成 AAUDIO_UNSPECIFIED ;

  • ② 默认值打开流 : 默认值 AAUDIO_UNSPECIFIED 状态下 , 如果打开 AAudio 音频流 , 系统会自动选择一个最佳的样本格式 , 这个值可能由 Android 设备决定 , 每个设备的值可能都不一样 ;



IV . AAudio 音频流 样本格式


AAudio 音频流 样本格式 :

  • ① 样本格式定义 : aaudio_format_t 是 int32_t 类型数据 , 该枚举有四种取值 ;
enum {
    AAUDIO_FORMAT_INVALID = -1,
    AAUDIO_FORMAT_UNSPECIFIED = 0,

    /**
     * This format uses the int16_t data type.
     * The maximum range of the data is -32768 to 32767.
     */
    AAUDIO_FORMAT_PCM_I16,

    /**
     * This format uses the float data type.
     * The nominal range of the data is [-1.0f, 1.0f).
     * Values outside that range may be clipped.
     *
     * See also 'floatData' at
     * https://developer.android.com/reference/android/media/AudioTrack#write(float[],%20int,%20int,%20int)
     */
    AAUDIO_FORMAT_PCM_FLOAT
};
typedef int32_t aaudio_format_t;
  • ② AAUDIO_FORMAT_UNSPECIFIED 格式 : 未定义格式 , 默认的格式 , 如果音频流打开系统跟自动选择合适的采样格式 ;
  • ③ AAUDIO_FORMAT_PCM_I16 格式 : 每个样本是 16 位 , 其取值范围是 -32768 ~ 32767 ;
  • ④ AAUDIO_FORMAT_PCM_FLOAT 格式 : 样本由浮点型表示 , 取值范围 -1.0 ~ +1.0 ;


V . AAudio 音频流 设置缓冲区大小 AAudioStream_setBufferSizeInFrames


1. 函数作用 : 在音频流播放时 , 有可能会产生阻塞 , 即 采样播放完毕 , 新采样还没到达 , 该函数可以 通过 改变 缓冲区大小阈值 , 调整 缓冲区的延迟 , 即 如果出现 阻塞 , 可以增大该缓冲区大小 ( 帧数 ) ;

2. 结合 XRun 值使用 : 通过 AAudioStream_getXRunCount() 方法 , 可以获取 欠载 ( UnderRun ) 或 超限 ( OverRun ) 的值 , 根据该 XRun 值进行缓冲区大小的调整 , 达到为每个音频设备设置合适的延迟的目的 ;

3. 可设置的最大值 : 通过 AAudioStream_getBufferCapacityInFrames() 函数可以获取 缓冲区可设置的最大帧数 , 设置帧数时 , 不能超过该数值 ;

4. 查看当前缓冲区大小 : 调用 AAudioStream_getBufferSizeInFrames() 方法 , 可以查看当前的缓冲区帧数 ;

文档中的说法是 : 获取 AAudio 音频流在不阻塞的情况下 , 可以读取 或 写入的最大帧数 , 理解不通 ;

5. AAudioStream_setBufferSizeInFrames 函数简介 :

  • ① 函数原型 : numFrames 是设置的新的缓冲区帧数 , stream 代表 AAudio 音频流指针 ;
AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(
  AAudioStream *stream,
  int32_t numFrames
)
  • ② 代码示例 :
        //设置当前缓冲区是多少帧
        bufferSize = AAudioStream_setBufferSizeInFrames(stream, bufferSize);

播放器缓冲区 : 这里的帧缓冲区指的是 AAudio 音频流的缓冲区 , 属于播放器 或 音频设备 的固有属性 ;
采样缓冲区 : 注意与采样缓冲区进行区分 , 采样缓冲区指的是 一次性向 AAudio 音频流 读取 或 写入的 字节数 , 注意区分这两个缓冲区 ;
电流产生 : 如果两个缓冲区设置不当 , 会造成音频卡顿 , 电流 , 刺啦 或者 啪啪 的声音 ;
帧大小 : 这里的帧可以理解成一个样本 , 如果是单声道 , 每帧一个样本 , 如果是双声道立体声 , 每帧 2 个样本 ;



VI . AAudio 音频流 采样率设置 AAudioStreamBuilder_setSampleRate


推荐使用默认设置 , 不要调用该方法 设置采样率 , 获取默认的最佳采样率 , 然后根据该采样率进行采样即可 ;

1 . AAudioStreamBuilder_setSampleRate 方法简介 :

  • ① 函数原型 : 设置 AAudio 音频流的采样率 ;
AAUDIO_API void AAudioStreamBuilder_setSampleRate(
  AAudioStreamBuilder *builder,
  int32_t sampleRate
)
  • ② sampleRate 参数 : sampleRate 参数就是采样率 , 其单位 赫兹 ( Hz ) , 一般情况下是 44100 Hz 或 48000 Hz , 代表一秒钟有 44100 或 48000 个采样 ;

2 . 最佳实践 :

  • ① 默认值 : 默认情况下 , 如果不调用该函数设置 AAudio 播放器的采样率 , 其值为 AAUDIO_UNSPECIFIED ;
  • ② 默认行为 : 在默认状态下 , 如果打开 AAudio 音频流 , 系统会自动分配一个最佳值 ;
  • ③ 应用开发推荐 : 打开默认采样率的音频流后 , 调用 AAudioStream_getSampleRate() 可以获取当前 AAudio 音频流的采样率 , 我们可以根据该采样率进行采样 ;

这也是我们推荐的做法 , 直接使用默认值即可 , 如果设置的值不合适 , 会造成 AAudio 音频流打开失败的后果 ;

  • ④ 出错情况 : 如果指定的采样率与音频设备不一致 , 打开音频流会失败 ;


VII . AAudio 音频流 获取当前采样率 AAudioStream_getSampleRate


AAudioStream_getSampleRate 简介 :

  • ① 函数原型 : 该函数用于获取当前 AAudio 音频流 采样率 ;
AAUDIO_API int32_t AAudioStream_getSampleRate(
  AAudioStream *stream
)
  • ② 代码示例 :
            // 获取音频流采样率
            sampleRate_ = AAudioStream_getSampleRate(playStream_);


VIII . AAudio 音频流 每帧采样数


设置每帧采样数 AAudioStreamBuilder_setSamplesPerFrame() :

  • ① 等同方法 : 该方法 与 AAudioStreamBuilder_setChannelCount() 方法 作用是相同的 ;
  • ② 每帧采样数 : 该值就是通道数 , 如果是单声道 , 每帧只有一个采样 , 如果是 双声道立体声 , 每帧有 2 个采样 ;
  • ③ 函数原型 :
AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(
  AAudioStreamBuilder *builder,
  int32_t samplesPerFrame
)

获取每帧采样数 AAudioStream_getSamplesPerFrame :

  • ① 等同方法 : 该方法 与 AAudioStream_getChannelCount() 方法 作用是相同的 ;
  • ② 每帧采样数 : 该值就是通道数 , 如果是单声道 , 每帧只有一个采样 , 如果是 双声道立体声 , 每帧有 2 个采样 ;
  • ③ 函数原型 :
AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(
  AAudioStream *stream
)
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中使用AAudio播放音频需要进行以下配置和步骤: 1. 首先,确保你的项目已经使用了最新的Android SDK和NDK版本。 2. 在你的项目的build.gradle文件中,添加以下依赖项: ``` implementation 'androidx.media:media:1.3.0' ``` 3. 在你的代码中,创建一个AAudio对象并进行初始化: ``` AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); AudioFormat audioFormat = new AudioFormat.Builder() .setSampleRate(44100) .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO) .build(); int bufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT); AAudioStream aaudioStream = new AAudioStream.Builder() .setAudioFormat(audioFormat) .setBufferSizeInFrames(bufferSize) .setPerformanceMode(AAudioStream.PERFORMANCE_MODE_LOW_LATENCY) .setSharingMode(AAudioStream.SHARING_MODE_SHARED) .setDirection(AAudioStream.DIRECTION_OUTPUT) .build(); ``` 4. 创建一个音频缓冲区,并将音频数据写入AAudio: ``` byte\[\] audioData = // 从文件或其他来源获取音频数据 int result = aaudioStream.write(audioData, 0, audioData.length, 0); ``` 5. 播放音频数据: ``` aaudioStream.requestStart(); ``` 这样就可以使用AAudioAndroid Studio中播放音频了。请注意,以上代码只是一个简单的示例,你可能需要根据你的具体需求进行适当的修改和调整。同时,还可以考虑使用oboe库来封装AAudio和OpenSL ES,以便在不同版本的Android设备上实现最佳的音频性能。 #### 引用[.reference_title] - *1* *2* [Android-Native开发系列之利用AAudio播放音频](https://blog.csdn.net/qq_34902522/article/details/128893756)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android端使用AAduio实现高性能音频](https://blog.csdn.net/u011686167/article/details/122830491)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值