Android AAudio——C API读/写音频流(五)

本文深入探讨Android AAudio的音频处理,包括直接读写和回调方式。直接读写涉及AAudioStream_write和AAudioStream_read函数,适合简单场景。回调方式提供异步处理,降低延迟,适用于实时音频应用。回调处理流程包括设置回调、处理数据和错误回调。回调方式的源码分析揭示了处理音频流的核心逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        对于音频流的操作,除了前面介绍的音频流打开、开始、暂停、停止和清除等,最主要的操作便是通过音频流的读/写操作来处理音频数据,这里我们就来介绍一下音频流读/写音频数据的操作。

一、音频数据处理

        当 audio stream 启动后,有两种方式来处理音频数据。

  • 通过 AAudioStream_write 和 AAudioStream_read 函数向流里写数据和读数据,使用此方式需要自己创建线程控制数据读写。
  • 通过 callback 的方式,使用此方式,会更高效,延迟更低,是官方推荐的方式。

1、直接读写数据

// 写入数据
AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream, const void *buffer,
            int32_t numFrames, int64_t timeoutNanoseconds)

// 读取数据
AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream, v
### 如何解码音频数据流 #### 使用FFmpeg库进行音频解码 在处理音频数据流时,可以利用FFmpeg库中的`avcodec_receive_frame`函数来完成解码操作。此过程涉及初始化编解码上下文以及接收并处理解码后的帧。 ```c // 初始化解码器配置... if (avcodec_send_packet(avctx, pkt) < 0) { // 错误处理逻辑... } while (ret >= 0) { ret = avcodec_receive_frame(avctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) return; else if (ret < 0) { // 解码错误处理... break; } // 处理解码成功的frame对象... } ``` 上述代码展示了发送包给解码器并通过循环调用`avcodec_receive_frame`获取已解码的音频帧[^1]。 #### 利用AAudio API管理音频流 对于Android平台上的应用程序来说,可以通过AAudio框架下的`AAudioStream`结构体实现对音频输入输出的支持。无论是播放还是录制声音文件都可以借助这个接口完成设置与控制工作。 ```cpp AAudioStreamBuilder* builder = nullptr; aaudio_result_t result = AAudio_createStreamBuilder(&builder); result = AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_I16); result = AAudioStreamBuilder_setChannelCount(builder, 2); // 双声道 result = AAudioStreamBuilder_setSampleRate(builder, sample_rate_hz); AAudioStream* stream = nullptr; result = AAudioStreamBuilder_openStream(builder, &stream); ``` 这段C++片段说明了创建和配置一个用于传输PCM格式立体声波形的新实例的方式[^2]。 #### FFmpeg内部的数据流动机制 当涉及到多媒体容器内的音轨部分时,每一个独立轨道都会被封装成`AVStream`实体,并且关联有一个专门负责其编码/解码工作的`AVCodecContext`环境变量。而具体的编译算法则由相应的`AVCodec`定义,这些组件共同协作实现了媒体资源的有效解析与再现功能[^3]。 #### 将解码后的音频合成为PCM样本 一旦完成了从压缩域到时间序列形式的变化之后,下一步就是要把得到的结果进一步加工为可以直接用来驱动扬声设备的声音脉冲串列——即所谓的线性量化表示法(Linear Pulse Code Modulation),简称LPCM或PCM。 ```c mad_stream_init(&mc->ms); mad_frame_init(&mc->mf); mad_synth_init(&mc->msynt); for (;;) { int err; /* ... */ mad_synth_frame(&mc->msynt, &mc->mf); memcpy(output_buffer, mc->msynt.pcm.samples[0], sizeof(*output_buffer)); } ``` 这里给出了一段基于libmad库的操作示范,它能够把MP3位流最终转变为我们所需要的原始采样数值集合[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c小旭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值