OpenSLES SLPlaybackRateItf SetRate适用于Android 4.x,但不适用于Android 5.x.
似乎SetRate接口在Android 5.x上没有实现。
以下是一些代码段,完整的代码可以在这里找到:https://github.com/jimrange/cocos2d-x/blob/audioEngineUpdate/cocos/audio/android/AudioEngine-inl.cpp
SLPlaybackRateItf _fdPlayerPlaybackRate;
SLObjectItf _fdPlayerObject;
为简洁起见,未显示其他初始化代码。
// get the playback rate interface
result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_PLAYBACKRATE, &_fdPlayerPlaybackRate);
if(SL_RESULT_SUCCESS != result){ ERRORLOG("get the rate interface failed"); break; }
SLpermille stepSize;
SLuint32 capabilities;
auto rangeResult = (*_fdPlayerPlaybackRate)->GetRateRange(_fdPlayerPlaybackRate, 0, &_minRate, &_maxRate, &stepSize, &capabilities);
if(SL_RESULT_SUCCESS != rangeResult)
{
log("%s error:%u",__func__, rangeResult);
}
此时
_minRate == 500
_maxRate == 2000
stepSize == 0
capabilities == SL_RATEPROP_NOPITCHCORAUDIO
稍后调用以下内容时,结果为SL_RESULT_SUCCESS,但播放速率不会改变。
void AudioEngineImpl::setPitch(int audioID,float pitch)
{
auto& player = _audioPlayers[audioID];
SLpermille playbackRate = (SLpermille)1000 * pitch;
if (playbackRate < player._minRate)
{
log("Warning: AudioEngine attempting to set rate:%d which is lower than minRate=%d.", playbackRate, player._minRate);
playbackRate = player._minRate;
}
else if (playbackRate > player._maxRate)
{
log("Warning: AudioEngine attempting to set rate:%d which is higher than maxRate=%d.", playbackRate, player._maxRate);
playbackRate = player._maxRate;
}
// This works on Android 4.4.4 on Nexus 7, but not on Android 5.x on Nexus 7 or Nexus 9.
auto result = (*player._fdPlayerPlaybackRate)->SetRate(player._fdPlayerPlaybackRate, playbackRate);
if(SL_RESULT_SUCCESS != result)
{
log("%s error:%u",__func__, result);
}
}
以下是我的体验:
请求SL_IID_PLAYBACKRATE接口返回SL_RESULT_SUCCESS。
我可以查询接口的功能,我得到的范围是500到2000,步长为0,功能标志为SL_RATEPROP_NOPITCHCORAUDIO。在Android 4.x和5.x上也是如此。
所以接口告诉我所有设置都很好并准备就绪。
调用SetRate会在Android 4.x和Android 5.x上返回SL_RESULT_SUCCESS。
但是在5.x上,SetRate对音频没有任何影响。
还有另一个SO帖子建议使用SL_RATEPROP_PITCHCORAUDIO,但我想使用SL_RATEPROP_NOPITCHCORAUDIO,以便在改变音频速率时没有音调校正。 SL_RATEPROP_NOPITCHCORAUDIO是默认设置,因此无需更改。
来自OpenSL_ES_Specification_1.0.1.pdf:
SL_RATEPROP_NOPITCHCORAUDIO - 以当前速率播放音频,但不进行音高修正。
SL_RATEPROP_PITCHCORAUDIO - 以当前速率播放音频,但使用音高修正。
我正在研究扩展Cocos2d-x AudioEngine的代码。
Cocos2d-x版本为3.7rc0,NDK版本为ndk-r10d。