android - Android 上的 OpenSL 播放速度高于应有的速度

标签 android c++ android-ndk opensl

我设法创建了一个 OpenSL 上下文,以便它播放声音。
但我仍然有一个问题:我将我的播放器的 samplesPerSec 设置为 44.100 Hz 但它实际上运行在 ~ 70.000 Hz。如何解决这个问题?

好吧,我会告诉你我做了什么(在 Source Code 完整):

PolyOpenSLInterface.cpp我正在初始化 OpenSL 并开始将缓冲区排队到我的 SLAndroidSimpleBufferQueueItf。 我通过以下方式创建播放器:

SLDataLocator_AndroidSimpleBufferQueue lDataLocatorIn;
lDataLocatorIn.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
lDataLocatorIn.numBuffers = 1;

SLDataFormat_PCM lDataFormat;
lDataFormat.formatType = SL_DATAFORMAT_PCM;
lDataFormat.numChannels = POLY_NUM_CHANNELS;
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_44_1; //sampling rate 44.100Hz
lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
lDataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
if(POLY_NUM_CHANNELS > 1){
    lDataFormat.channelMask = SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_LEFT;
} else {
    lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
}
lDataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

SLDataSource lDataSource;
lDataSource.pLocator = &lDataLocatorIn;
lDataSource.pFormat = &lDataFormat;

SLDataLocator_OutputMix lDataLocatorOut;
lDataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX;
lDataLocatorOut.outputMix = mOutputMixObj;

SLDataSink lDataSink;
lDataSink.pLocator = &lDataLocatorOut;
lDataSink.pFormat = NULL;

const SLuint32 lSoundPlayerIIDCount = 2;
const SLInterfaceID lSoundPlayerIIDs[] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLboolean lSoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };

lRes = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj, &lDataSource, &lDataSink, lSoundPlayerIIDCount, lSoundPlayerIIDs, lSoundPlayerReqs);
lRes = (*mPlayerObj)->Realize(mPlayerObj, SL_BOOLEAN_FALSE);

我注册的回调看起来像这样(我使用已经使用过的缓冲区并将下一个样本写入其中并再次将缓冲区放入队列中):

void OpenSLAudioInterface::queueCallback(SLAndroidSimpleBufferQueueItf caller, void* pContext){
    OpenSLAudioInterface *audioInterface = (OpenSLAudioInterface*) pContext;
    if(audioInterface->buffer && audioInterface->getMixer()) {
        int16_t *out = (int16_t*)audioInterface->buffer;
        audioInterface->getMixer()->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER);
        (*(audioInterface->mPlayerQueue))->Enqueue(audioInterface->mPlayerQueue, out, sizeof(int16_t)*POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS);
    }
}

那么谁能解释一下,为什么声音的播放速度比正常情况快 ~2 倍,以及为什么我需要混合以填充缓冲区的样本超过 44.100Hz ~2?
我是否需要使用循环缓冲区(我在这里使用的缓冲区是否仍被 OpenSL 使用?)?

提前感谢您的每一个建议和帮助!

最佳答案

所以我解决了这个问题。
我实际上对 OpenSL 进行了两次初始化,因此也开始从一个源写入两个并发缓冲区队列 - 这导致一半的帧无法正常播放。

关于android - Android 上的 OpenSL 播放速度高于应有的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37589003/

相关文章:

javascript - 链接到 Play 商店 - 智能应用横幅 - Android

java - 拆分字符串,如果它有数字

c++ - 为什么我们为glfwCreateWindow使用指针? -OpenGL

video - 使用 FFMpeg 在 Android 中处理视频文件

Android 翻译动画,如交换两个 View

android - 如何在 Flutter 中水平居中 FloatingActionButton?

C++ Qt - 打开文本文件操作失败

c++ - 获取宏参数的最后一个字符

c++ - 安卓 native NDK OpenGL ES : unimplemented API

android-ndk - 在 NDK 中使用 "exec()"