文章目录- I . AAudio 音频流 读写操作 简介
- II . AAudio 音频流 读写操作 阻塞时间设定
- III . AAudio 音频流 读取 固定帧数 操作 注意点
- IV . AAudio 音频流 写出音频数据 操作 注意点
- V . AAudio 音频流 读取方法 AAudioStream_read 原型
- VI . AAudio 音频流 读取方法 简介
- VII . AAudio 音频流 写出方法 AAudioStream_write 原型
I . AAudio 音频流 读写操作 简介
1 . 创建 AAudio 音频流 : 使用 AAudio 音频流构建器 AAudioStreamBuilder 创建 AAudio 音频流后 , 调用 AAudioStreamBuilder_openStream 打开 AAudio 音频流 , 此时音频流正式创建 ;
2 . 开启 AAudio 音频流播放 : 调用 AAudioStream_requestStart 方法 , 即可开始 AAudio 音频流的播放 ;
3 . 读写操作前提 ( Started 状态 ) : 当 AAudio 处于 Started 状态后 , 便可进行 AAudio 音频流的读写操作 ;
4 . 读写操作函数 :
- ① 读取操作 : 从 AAudio 音频流中读取数据到内存中 , AAudioStream_read(stream, buffer, numFrames, timeoutNanos) ;
- ② 写出操作 : 将内存中的数据写出到 AAudio 音频流中 , AAudioStream_write(stream, buffer, numFrames, timeoutNanos) ;
5 . 读写数据格式 : AAudio 音频流读写数据的格式 , 与 AAudioStream_getDataFormat() 方法返回的格式 的 采样率 , 样本格式 必须一致 , 否则会出错 ;
II . AAudio 音频流 读写操作 阻塞时间设定
阻塞时间设定 :
- ① 指定帧数读写 : 如果要读写固定帧数的数据 , 需要设置一个大于 0 的超时时间 , 因为可能会在很长时间内无法读取到足够的数据 , 而一直阻塞 , 导致程序无法执行下去 , 这里设置一个超时时间避免这种情况发生 ;
- ② 不限定帧数读写 : 如果读写数据不限定帧数 , 则可以将超时时间设置成 0 , 读写的帧数就是实际操作的帧数 ;
III . AAudio 音频流 读取 固定帧数 操作 注意点
AAudio 音频流数据读取 :
- ① 帧数验证 : 从 AAudio 音频流中读取数据时 , 需要验证当前读取的帧数 ;
- ② 超时读取 : 如果读取时在超时时间内未能读取到指定 的 numFrames 帧数的数据 , 则也会继续执行, 此时 audioData 中除了读取的数据之外 , 还有一部分未知数据 ;
- ③ 未知数据 : 因为读取的数据中可能包含未知数据 , 如果将未知数据当做音频采样数据 , 会造成不可预知后果 , 出现电流等干扰 ;
- ④ 处理方法 : 将非读取的数据使用 0 填充 , 这些数据播放出来就是静音的效果, 没有意外的电流或杂音 ;
- ⑤ 代码示例 : 设定读取 numFrames 帧数据到 audioData 指针指向的内存中 , 如果 timeout 纳秒内还没读取完毕 , 继续执行下面的代码 , 之后首先判定是否完整读取了 numFrames 帧的数据 , 如果读取了帧数小于 numFrames 需要将后半部分的随机数据设置为 0 ;
//读取 numFrames 帧数据 , 如果帧数不够则一直阻塞 , 直到 timeout 毫秒后 超时 , 然后才能解除阻塞继续执行 ;
aaudio_result_t result =
AAudioStream_read(stream, audioData, numFrames, timeout);
//如果出现了错误 , 进行错误处理逻辑 ;
if (result < 0) {
// 错误处理逻辑
}
//如果实际读取的帧数 与 设定读取的帧数不一致 , 一般是读取的帧数小于设定的读取帧数 , 这是由于超时造成的 ;
if (result != numFrames) {
// 将 audioData 指针指向的内存中 除 numFrames 帧音频采样数据之外的 剩余其它数据设置成 0 , 即静音效果 ;
memset(static_cast<sample_type*>(audioData) result * samplesPerFrame, 0,
sizeof(sample_type) * (numFrames - result) * samplesPerFrame);
}
IV . AAudio 音频流 写出音频数据 操作 注意点
AAudio 音频流数据写出 :
- ① 缓冲区 : 先将数据放入缓冲区 , 该缓冲区大小 与 AAudio 音频流整体性能相关 ;
- ② 启动音频流 : 将缓冲区中的数据写入 AAudio 音频流 , 将 音频流 启动 ;
- ③ 超时设置 : 写出数据时 , timeoutNanos 参数必须设置成 0 , 代表其超时时间是 0 纳秒 , 保证该操作是非阻塞操作 ;
- ④ 缓冲区数据格式 : 缓冲区中存储的音频数据格式 与 AAudioStream_getDataFormat() 方法返回的格式必须一致 ;
V . AAudio 音频流 读取方法 AAudioStream_read 原型
AAudioStream_read 方法简介 :
- ① 函数原型 : 从 AAudio 音频流中读取数据 , 用于录音 ;
AAUDIO_API aaudio_result_t AAudioStream_read(
AAudioStream *stream,
void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds
)
- ② AAudioStream *stream 参数 : AAudio 音频流 ;
- ③ void *buffer 参数 : 从 AAudio 音频流中读取的音频数据指针 , 该指针指向的内存地址中存储读取的音频数据 ;
- ④ int32_t numFrames 参数 : 读取的帧数 , 每帧的样本数就是通道数 ;
- ⑤ int64_t timeoutNanoseconds 参数 : AAudio 读取音频流的超时时间 , 如果在这个 timeoutNanoseconds 纳秒内没有读取到 numFrames 帧数据 , 就会解除阻塞 , 继续执行后续代码 ;
- ⑥ 返回值 : aaudio_result_t 类型 , 返回实际读取到的帧数 , 如果出现错误 , 会返回错误码 ;
VI . AAudio 音频流 读取方法 简介
1 . 方法阻塞时间 : AAudioStream_read 方法执行时会阻塞当前线程 , 满足下面两种条件的任意一种 , 线程阻塞解除 ;
- ① 执行完毕 : 从 AAudio 音频流中读取了指定帧数的音频数据 ;
- ② 执行超时 : 没有读取到足够的帧数 , 但是超过了指定的超时时间 , 这种情况返回值返回的是实际读取的音频数据帧数 ;
2 . 方法非阻塞设置 : 如果将 AAudioStream_read 方法的 timeoutNanoseconds 参数设置成 0 , 那么该方法不会阻塞 , 尝试读取一次 , 不管读取到多少数据 , 都会立刻继续执行后续代码 ;
3 . 超时时间说明 : 超时时间 timeoutNanoseconds 纳秒值 , 是一个相对的时间 , 如果线程 sleep 后 , 该时间也会继续计时 , 如果 sleep 结束 , 发现超时时间已过 , 会瞬间解除 AAudioStream_read 方法的阻塞 ;
VII . AAudio 音频流 写出方法 AAudioStream_write 原型
AAudioStream_write 写出方法 :
- ① 方法原型 : 向 AAudio 音频流中写出音频数据 , 用于播放音频 ;
AAUDIO_API aaudio_result_t AAudioStream_write(
AAudioStream *stream,
const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds
)
- ② AAudioStream *stream 参数 : AAudio 音频流 ;
- ③ void *buffer 参数 : 向 AAudio 音频流中写出的音频数据指针 , 该指针指向的内存地址中存储读取的音频数据首地址 ;
- ④ int32_t numFrames 参数 : 要写出的帧数 , 每帧的样本数就是通道数 ;
- ⑤ int64_t timeoutNanoseconds 参数 : AAudio 写出音频流的超时时间 , 如果在这个 timeoutNanoseconds 纳秒内没有写出 numFrames 帧数据 , 就会解除阻塞 , 继续执行后续代码 ;
- ⑥ 返回值 : aaudio_result_t 类型 , 返回实际写出到 AAudio 音频流的帧数 , 如果出现错误 , 会返回错误码 ;