【Android 高性能音频】AAudio 音频流 读写操作 ( 音频流读写数据 | 阻塞时间设定 | 注意事项 | AAudioStream_read | AAudioStream_write )

简介: 【Android 高性能音频】AAudio 音频流 读写操作 ( 音频流读写数据 | 阻塞时间设定 | 注意事项 | AAudioStream_read | AAudioStream_write )

文章目录

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 音频流的帧数 , 如果出现错误 , 会返回错误码 ;


目录
相关文章
|
1月前
|
数据库 Android开发 开发者
构建高性能微服务架构:从理论到实践构建高效Android应用:探究Kotlin协程的优势
【2月更文挑战第16天】 在当今快速迭代和竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性和独立部署能力而受到企业的青睐。本文将深入探讨如何构建一个高性能的微服务系统,涵盖从理论基础到具体实现的各个方面。我们将重点讨论服务拆分策略、通信机制、数据一致性以及性能优化等关键主题,为读者提供一个清晰、实用的指南,以便在复杂多变的业务环境中构建和维护健壮的微服务体系结构。 【2月更文挑战第16天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着技术的不断进步,Kotlin作为一种现代编程语言,在Android开发中被广泛采用,尤其是其协程特性为异步编程带来了革命性的改进。本文旨在深入
241 5
|
4月前
|
Android开发
【Android App】蓝牙的设备配对、音频传输、点对点通信的讲解及实战(附源码和演示 超详细)
【Android App】蓝牙的设备配对、音频传输、点对点通信的讲解及实战(附源码和演示 超详细)
100 0
|
4月前
|
XML Java Android开发
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
74 0
|
3天前
|
Android开发 内存技术
Android 通过tinyalsa调试解决录制和播放音频问题
Android 通过tinyalsa调试解决录制和播放音频问题
21 1
|
4月前
|
XML 编解码 算法
Android开发音效中录制WAV音频和录制MP3音频的讲解及实战(超详细 附源码)
Android开发音效中录制WAV音频和录制MP3音频的讲解及实战(超详细 附源码)
70 0
|
4月前
|
XML Java Android开发
Android 开发中原始音频的录播和和自定义音频控制条的讲解及实战(超详细 附源码)
Android 开发中原始音频的录播和和自定义音频控制条的讲解及实战(超详细 附源码)
27 0
|
4月前
|
XML 存储 Java
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
42 0
|
4月前
|
XML Java Android开发
Android App开发音量调节中实现拖动条和滑动条和音频管理器AudioManager讲解及实战(超详细 附源码和演示视频)
Android App开发音量调节中实现拖动条和滑动条和音频管理器AudioManager讲解及实战(超详细 附源码和演示视频)
77 0
|
5天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
28天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
14 0