我一直在尝试通过适用于Android的OpenSL ES API创建音频播放器。但是,当我尝试运行我的代码时出现错误,这表示我将错误的参数输入CreateAudioPlayer()
:
05-16 12:16:40.593: ERROR/libOpenSLES(2020): channelMask=0x100 numChannels=1
05-16 12:16:40.593: ERROR/AudioProcessor_Native(2020): Invalid parameter found
05-16 12:16:40.593: ERROR/AudioProcessor_Native(2020): Unable to create player object
但是,我找不到任何错误或无效的参数。我已经检查了其中任何一个,并且没有在网上找到任何表明我的组合无效的内容。代码如下所示:
JNIEXPORT jboolean JNICALL Java_org_test_opensl_AudioProcessor_initPlayer(JNIEnv* env, jobject thiz){
SLresult result;
// Configure Buffer Queue.
SLDataLocator_AndroidSimpleBufferQueue bufferQueue;
bufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
bufferQueue.numBuffers = MAX_BUFFERS;
// Configure data format.
SLDataFormat_PCM pcm;
pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
pcm.channelMask = SL_SPEAKER_BACK_CENTER;
pcm.containerSize = 16;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
pcm.formatType = SL_DATAFORMAT_PCM;
pcm.numChannels = 1;
pcm.samplesPerSec = SL_SAMPLINGRATE_8;
// Configure Audio Source.
SLDataSource source;
source.pFormat = &pcm;
source.pLocator = &bufferQueue;
// Configure output mix.
SLDataLocator_OutputMix outputMix;
outputMix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
outputMix.outputMix = outputMixObject;
// Configure Audio sink.
SLDataSink sink;
sink.pFormat = NULL;
sink.pLocator = &outputMix;
// Create Audio player.
const SLInterfaceID ids[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
result = (*engineInstance)->CreateAudioPlayer(engineInstance, &playerObject, &source,
&sink, 1, ids, req);
if(checkError(result, "Unable to create player object") == -1){
return JNI_FALSE;
}
// Realize Audio player.
result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
if(checkError(result, "Unable to realize player object") == -1){
return JNI_FALSE;
}
// Get the Audio player interface.
result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerInstance);
if(checkError(result, "Unable to get player interface") == -1){
return JNI_FALSE;
}
// Get the Player Buffer Queue interface.
result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
&playerBufferQueue);
if(checkError(result, "Unable to get player buffer interface") == -1){
return JNI_FALSE;
}
// Set the player's state to playing.
result = (*playerInstance)->SetPlayState(playerInstance, SL_PLAYSTATE_PLAYING);
if(checkError(result, "Unable to set player's state to playing") == -1){
return JNI_FALSE;
}
return JNI_TRUE;
}
checkError()
是一种自定义的错误检查方法。
任何人都知道为什么会失败?正如我所说,所有参数对我来说都是有效的,我已经检查了source,outputmix或sink对象中的无效组合,但没有......
答案 0 :(得分:4)
既不是你设置字段的顺序,也不是容器的大小,而是产生差异。我觉得通过为channelMask设置适当的值来解决您的问题。
pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
而不是
pcm.channelMask = SL_SPEAKER_BACK_CENTER;
答案 1 :(得分:0)
我已经通过良好,充足的文档解决了这个问题,但更多的是运气。事实证明SLDataFormat_PCM
对象中的PCM属性不正确....
当我将其更改为:
// Configure data format.
SLDataFormat_PCM pcm;
pcm.formatType = SL_DATAFORMAT_PCM;
pcm.numChannels = 1;
pcm.samplesPerSec = SL_SAMPLINGRATE_8;
pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
它可以毫不拖延地创建AudioPlayer ......
我不知道为什么会发生这种情况,也许是因为它是一个需要按正确顺序设置的结构?我不知道......虽然我不能想象它...除非它更像是一个或多个变量的记忆图,我可以想象......
无论如何,我修好了...... 叹息