我正在使用Android oboe库在音乐游戏中获得高性能音频。
在资产文件夹中,我有2个.raw文件(均为48000Hz 16位PCM wav和大约60kB) std_kit_sn.raw std_kit_ht.raw
这些作为SoundRecordings加载到内存中并添加到混音器中。 kSampleRateHz为48000:
stdSN= SoundRecording::loadFromAssets(mAssetManager, "std_kit_sn.raw");
stdHT= SoundRecording::loadFromAssets(mAssetManager, "std_kit_ht.raw");
mMixer.addTrack(stdSN);
mMixer.addTrack(stdFT);
// Create a builder
AudioStreamBuilder builder;
builder.setFormat(AudioFormat::I16);
builder.setChannelCount(1);
builder.setSampleRate(kSampleRateHz);
builder.setCallback(this);
builder.setPerformanceMode(PerformanceMode::LowLatency);
builder.setSharingMode(SharingMode::Exclusive);
LOGD("After creating a builder");
// Open stream
Result result = builder.openStream(&mAudioStream);
if (result != Result::OK){
LOGE("Failed to open stream. Error: %s", convertToText(result));
}
LOGD("After openstream");
// Reduce stream latency by setting the buffer size to a multiple of the burst size
mAudioStream->setBufferSizeInFrames(mAudioStream->getFramesPerBurst() * 2);
// Start the stream
result = mAudioStream->requestStart();
if (result != Result::OK){
LOGE("Failed to start stream. Error: %s", convertToText(result));
}
LOGD("After starting stream");
它们被适当地调用以在需要的时间使用标准代码(根据Google教程):
stdSN->setPlaying(true);
stdHT->setPlaying(true); //Nasty Sound
音频回调是标准的(根据Google教程):
DataCallbackResult SoundFunctions::onAudioReady(AudioStream *mAudioStream, void *audioData, int32_t numFrames) {
// Play the stream
mMixer.renderAudio(static_cast<int16_t*>(audioData), numFrames);
return DataCallbackResult::Continue;
}
std_kit_sn.raw可以正常播放。但是std_kit_ht.raw有一个令人讨厌的失真。两者都以低延迟播放。为什么一个人玩得很好,而另一个人却令人讨厌呢?
答案 0 :(得分:1)
我加载了您的示例项目,我相信您听到的失真是由于混音期间的剪切/环绕引起的。
样本中的Mixer
对象是求和混合器。 It just adds the values of each track together and outputs the sum。
您需要添加一些代码来减少每个音轨的音量,以避免超出int16_t
的限制(尽管欢迎您在双簧管项目中提交错误,我将尝试添加此错误在即将发布的版本中)。如果超过此限制,则会缠绕,从而导致变形。
此外,您的应用程序被硬编码为以22050帧/秒的速度运行。这将导致大多数移动设备出现次优延迟,因为流被迫上采样到音频设备的本机帧速率。更好的方法是在打开流时使采样率保持不确定状态-这将为您提供当前音频设备的最佳帧率-然后在源文件上使用重采样器以该帧率提供音频。