【发布时间】:2016-06-28 17:46:22
【问题描述】:
我设法创建了一个 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 times faster 播放的声音比它应该播放的要多,为什么我需要混合以填充缓冲区的样本超过 44.100Hz 的因子 ~2?
我是否需要使用循环缓冲区(我在这里使用的缓冲区是否仍被 OpenSL 使用?)?
提前感谢您的每一个建议和帮助!
【问题讨论】:
-
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_48;您的采样率为 48kHz,但您说您正在尝试以 44.1kHz 播放音频。另一件事来自lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;这一行 - 我看到这是每个样本 PCM 音频数据 16 位。但通常SL_PCMSAMPLEFORMAT_FIXED_8在大多数情况下都可以找到。 -
哦..我编辑了问题,因为我将其调整为 44.1 以符合项目默认值.. int16_t 不应该使用 16 位吗? (虽然我会用 8bit 测试它)
-
@ReazMurshed nope 8bit 把声音搞砸了....应该是 16bit。
标签: android c++ android-ndk opensl