【Android 高性能音频】AAudio 音频流 读写操作 ( 音频流读写数据 | 阻塞时间设定 | 注意事项 | AAudioStream_read | 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 音频流的帧数 , 如果出现错误 , 会返回错误码 ;
发布了252 篇原创文章 · 获赞 1013 · 访问量 168万+

猜你喜欢

转载自blog.csdn.net/han1202012/article/details/103211048
今日推荐