OpenSLES SLPlaybackRateItf SetRate无法在Android 5.x上运行,但适用于Android 4.x

时间:2015-07-20 22:47:26

标签: android c++ audio android-ndk

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。

0 个答案:

没有答案