Android Studio中使用Oboe库生成声音时长不符问题求助
Oboe库生成声音仅播放不到1秒噪音的问题解决
问题描述
在Android Studio项目中使用Oboe库生成声音,按官方文档编写代码后,仅能听到不到1秒的噪音,增大缓冲区和帧数也无法解决。预期声音时长应为约3.64秒(80096样本 ÷ 22000采样率),原代码如下:
#include "createStream.h" int main() { oboe::AudioStreamBuilder streamBuilder; streamBuilder.setSampleRate(22000); std::shared_ptr<oboe::AudioStream> mStream; oboe::Result result = streamBuilder.openStream(mStream); if (result != oboe::Result::OK) { return 10; } result = mStream->requestStart(); int16_t buffer[80096]; int numFrames = sizeof(buffer) / sizeof(buffer[0]); for (int i = 0; i < 80096; i++) { int a = rand() % 65536; buffer[i] = a; } mStream->write(buffer, numFrames, -1); if (result != oboe::Result::OK) { return 9; } mStream->requestStop(); mStream->close(); return 150; }
问题原因
- 帧数计算错误:Oboe默认创建立体声(2通道)流,每个音频帧包含2个
int16_t样本。原代码直接将缓冲区样本数当作帧数传入write(),导致Oboe尝试读取80096帧(160192个样本),远超缓冲区容量,触发越界读取,实际仅播放部分数据就终止。 - 流过早关闭:
write()完成后立即调用requestStop()和close(),此时音频硬件缓冲区仍有未播放数据,直接停止会截断剩余音频。 - 未检查关键操作结果:
requestStart()的启动结果未校验,可能导致后续写入操作无效。
解决方案及修正代码
- 显式设置单声道流,简化帧数计算;或根据实际通道数计算正确帧数
- 写入完成后等待音频播放完毕再停止流
- 校验所有Oboe操作的返回结果
修正后的代码:
#include "createStream.h" #include <cstdlib> #include <ctime> #include <chrono> #include <thread> int main() { // 初始化随机数种子 srand(time(nullptr)); oboe::AudioStreamBuilder streamBuilder; streamBuilder.setSampleRate(22000); // 显式设置单声道,避免默认立体声的帧数计算问题 streamBuilder.setChannelCount(oboe::ChannelCount::Mono); streamBuilder.setFormat(oboe::AudioFormat::I16); std::shared_ptr<oboe::AudioStream> mStream; // 打开流并校验结果 oboe::Result result = streamBuilder.openStream(mStream); if (result != oboe::Result::OK) { return 10; } // 启动流并校验结果 result = mStream->requestStart(); if (result != oboe::Result::OK) { mStream->close(); return 11; } const int sampleCount = 80096; int16_t buffer[sampleCount]; // 生成-32768到32767的有符号16位随机样本 for (int i = 0; i < sampleCount; i++) { buffer[i] = static_cast<int16_t>(rand() % 65536 - 32768); } // 单声道下样本数等于帧数 int numFrames = sampleCount; // 写入数据并校验结果 result = mStream->write(buffer, numFrames, -1); if (result != oboe::Result::OK) { mStream->requestStop(); mStream->close(); return 9; } // 等待音频播放完毕:按采样率计算时长,额外加100ms缓冲 double durationSeconds = static_cast<double>(sampleCount) / mStream->getSampleRate(); std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(durationSeconds * 1000) + 100)); // 停止并关闭流,等待流完全停止 mStream->requestStop(); mStream->waitForStateChange(oboe::StreamState::Started, nullptr, 1000 * oboe::kNanosPerMillisecond); mStream->close(); return 150; }
内容的提问来源于stack exchange,提问作者cs_guy98
相关产品推荐
相关产品推荐

