红色标题是本博客讲解的内容 , 黑色是前几篇讲过的内容 ;
使用 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_);
下面会着重对上面的流程细节进行详细解析 ; 每个方法的参数 , 原理 , 返回值 等细节都会讲解到 ;
1 . AAudio 音频流通道数设置 :
AAUDIO_API void AAudioStreamBuilder_setChannelCount(
AAudioStreamBuilder *builder,
int32_t channelCount
)
// 设置通道个数
AAudioStreamBuilder_setChannelCount(builder, sampleChannels_);
2 . 默认处理 :
3. 指定通道值情况处理 : 如果指定了通道数 , 那么打开流时会使用该通道数 ; 如果通道数与设备不匹配 , 那么 AAudio 音频流打开时会报错 ;
1 . AAudio 音频流格式设置 :
AAUDIO_API void AAudioStreamBuilder_setFormat(
AAudioStreamBuilder *builder,
aaudio_format_t format
)
// 设置音频格式
AAudioStreamBuilder_setFormat(builder, sampleFormat_);
2 . 默认设置 :
AAudio 音频流 样本格式 :
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;
1. 函数作用 : 在音频流播放时 , 有可能会产生阻塞 , 即 采样播放完毕 , 新采样还没到达 , 该函数可以 通过 改变 缓冲区大小阈值 , 调整 缓冲区的延迟 , 即 如果出现 阻塞 , 可以增大该缓冲区大小 ( 帧数 ) ;
2. 结合 XRun 值使用 : 通过 AAudioStream_getXRunCount() 方法 , 可以获取 欠载 ( UnderRun ) 或 超限 ( OverRun ) 的值 , 根据该 XRun 值进行缓冲区大小的调整 , 达到为每个音频设备设置合适的延迟的目的 ;
3. 可设置的最大值 : 通过 AAudioStream_getBufferCapacityInFrames() 函数可以获取 缓冲区可设置的最大帧数 , 设置帧数时 , 不能超过该数值 ;
4. 查看当前缓冲区大小 : 调用 AAudioStream_getBufferSizeInFrames() 方法 , 可以查看当前的缓冲区帧数 ;
文档中的说法是 : 获取 AAudio 音频流在不阻塞的情况下 , 可以读取 或 写入的最大帧数 , 理解不通 ;
5. AAudioStream_setBufferSizeInFrames 函数简介 :
AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(
AAudioStream *stream,
int32_t numFrames
)
//设置当前缓冲区是多少帧
bufferSize = AAudioStream_setBufferSizeInFrames(stream, bufferSize);
播放器缓冲区 : 这里的帧缓冲区指的是 AAudio 音频流的缓冲区 , 属于播放器 或 音频设备 的固有属性 ; 采样缓冲区 : 注意与采样缓冲区进行区分 , 采样缓冲区指的是 一次性向 AAudio 音频流 读取 或 写入的 字节数 , 注意区分这两个缓冲区 ; 电流产生 : 如果两个缓冲区设置不当 , 会造成音频卡顿 , 电流 , 刺啦 或者 啪啪 的声音 ; 帧大小 : 这里的帧可以理解成一个样本 , 如果是单声道 , 每帧一个样本 , 如果是双声道立体声 , 每帧 2 个样本 ;
推荐使用默认设置 , 不要调用该方法 设置采样率 , 获取默认的最佳采样率 , 然后根据该采样率进行采样即可 ;
1 . AAudioStreamBuilder_setSampleRate 方法简介 :
AAUDIO_API void AAudioStreamBuilder_setSampleRate(
AAudioStreamBuilder *builder,
int32_t sampleRate
)
2 . 最佳实践 :
这也是我们推荐的做法 , 直接使用默认值即可 , 如果设置的值不合适 , 会造成 AAudio 音频流打开失败的后果 ;
AAudioStream_getSampleRate 简介 :
AAUDIO_API int32_t AAudioStream_getSampleRate(
AAudioStream *stream
)
// 获取音频流采样率
sampleRate_ = AAudioStream_getSampleRate(playStream_);
设置每帧采样数 AAudioStreamBuilder_setSamplesPerFrame() :
AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(
AAudioStreamBuilder *builder,
int32_t samplesPerFrame
)
获取每帧采样数 AAudioStream_getSamplesPerFrame :
AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(
AAudioStream *stream
)