什么是oboe?
oboe是谷歌推出用于在Android上实现高性能音频应用的c++库,支持API16以上Android版本。在API27以上使用AAudio实现,27以下使用OpenSL ES实现,以提供最好的音频能力。适用于低延迟、高互动的场景,比如耳返功能、高互动游戏等。
如何使用oboe?
官方指导文档在这里,可以通过两种方式使用oboe,这里是把源码拉下来编译到项目。
1. 下载oboe库->https://github.com/google/oboe
2. 修改项目CMakeLists.txt
添加oboe源文件路径
# Set the path to the Oboe directory.
set (OBOE_DIR ***PATH TO OBOE***)
# Add the Oboe library as a subdirectory in your project.
# add_subdirectory tells CMake to look in this directory to
# compile oboe source files using oboe's CMake file.
# ./oboe specifies where the compiled binaries will be stored
add_subdirectory (${OBOE_DIR} ./oboe)
# Specify the path to the Oboe header files.
# This allows targets compiled with this CMake (application code)
# to see public Oboe headers, in order to access its API.
include_directories (${OBOE_DIR}/include)
添加oboe到target_link_libraries命令
target_link_libraries(native-lib oboe)
3. 使用oboe进行录音或者播放
成功添加oboe到项目中编译通过后,很容易就能使用oboe的api实现播放或者录音,编译遇到问题的话,可以从下载的oboe源码demo中参考CMakeLists.txt。
第一步:导入oboe头文件
#include <oboe/Oboe.h>
第二步:创建builder并设置参数
oboe::AudioStreamBuilder builder;
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setSharingMode(oboe::SharingMode::Exclusive)
->setCallback(myCallback)
->setFormat(oboe::AudioFormat::Float);
由于每个方法返回的是builder本身,所以可以链式调用,具体的参数意义可以查询官方文档,这里指定direction为Output意味着用于播放音频。
第三步:设置回调接口
上面代码中setCallback方法设置的是AudioStreamCallback
对象。在音频流请求数据时,会回调onAudioReady
方法
class MyCallback : public oboe::AudioStreamCallback {
public:
oboe::DataCallbackResult
onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
// We requested AudioFormat::Float so we assume we got it.
// For production code always check what format
// the stream has and cast to the appropriate type.
auto *outputData = static_cast<float *>(audioData);
// Generate random numbers (white noise) centered around zero.
const float amplitude = 0.2f;
for (int i = 0; i < numFrames; ++i){
outputData[i] = ((float)drand48() - 0.5f) * 2 * amplitude;
}
return oboe::DataCallbackResult::Continue;
}
};
其中,如果是播放音频,需要在audioData
指向的缓冲区填充数据,如果是录音,audioData
则是录音到的数据。方法返回的值决定流的操作是继续还是停止。
第四步:播放音频
在设置完各种参数以及回调之后,可以通过调用builder的openStream()
方法创建音频流,然后就可以执行播放操作了
注意:获取到创建的音频流时,应该先判断一下音频流的格式是否符合需求
oboe::AudioFormat format = stream->getFormat();
LOGI("AudioStream format is %s", oboe::convertToText(format));
音频流状态切换
一般我们在开始播放的地方调用requestStart()
,然后在onAudioReady()
回调中处理数据,在结束播放是调用requestStop()
即可,要注意的是,request*()
方法是异步,音频流状态并不会立刻改变。
第五步:关闭音频流
在不再播放或录音时,请务必关闭音频流,直接调用close()
方法即可。
另外,如果音频流对象作用域结束,也会自动关闭
{
ManagedStream mStream;
AudioStreamBuilder().build(mStream);
mStream->requestStart();
} // Out of this scope the mStream has been automatically closed
以上就能实现简单播放音频功能了,需要更深入了解oboe的使用和其他API,例如线程安全问题、阻塞与非阻塞数据处理,建议详细阅读官方文档。
网友评论