OpenSLES SLPlaybackRateItf SetRate不适用于Android 5.x,但适用于Android 4.x

OpenSLES SLPlaybackRateItf SetRate不适用于Android 5.x,但适用于Android 4.x,android,c++,audio,android-ndk,Android,C++,Audio,Android Ndk,OpenSLES SLPlaybackRateItf SetRate适用于Android 4.x,但不适用于Android 5.x 似乎SetRate接口在Android 5.x上没有实现 下面是一些代码片段,完整的代码可以在这里找到: 为简洁起见,未显示其他初始化代码 // get the playback rate interface result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_PLAYBACKRA

OpenSLES SLPlaybackRateItf SetRate适用于Android 4.x,但不适用于Android 5.x

似乎SetRate接口在Android 5.x上没有实现

下面是一些代码片段,完整的代码可以在这里找到:

为简洁起见,未显示其他初始化代码

// 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

_最大速率==2000

步长==0

能力==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);
    }
}
void AudioEngineImpl::设置音高(int-audioID,float-pitch)
{
自动和播放器=_AudioPlayer[audioID];
斯佩尔米尔后卫率=(斯佩尔米尔)1000*节;
如果(回放速率<玩家速率)
{
日志(“警告:AudioEngine试图设置低于minRate=%d.”的速率:%d”,播放速率,播放器。\u minRate);
后卫率=球员;
}
否则,如果(回放速率>玩家。\u最大速率)
{
日志(“警告:AudioEngine试图设置速率:%d,该速率高于maxRate=%d.”,播放速率,播放器。\u maxRate);
playbackRate=玩家;
}
//这适用于Nexus7上的Android 4.4.4,但不适用于Nexus7或Nexus9上的Android 5.x。
自动结果=(*player.\u fdPlayerPlaybackRate)->SetRate(player.\u fdPlayerPlaybackRate,playbackRate);
if(SL_RESULT_SUCCESS!=结果)
{
日志(“%s错误:%u”,函数,结果);
}
}
以下是我的经历:

请求SL_IID_PLAYBACKRATE接口返回SL_RESULT_SUCCESS

我可以查询接口的功能,得到的范围为500到2000,步长为0,功能标志为SL_RATEPROP_NOPITCHCORAUDIO。这在安卓4.x和5.x上是相同的

所以界面告诉我所有的设置都很好,准备好了

在Android 4.x和Android 5.x上调用SetRate返回SL_结果_成功

但是在5.x上,设置速率对音频没有任何影响

还有一篇SO帖子建议使用SL_RATEPROP_PITCHCORAUDIO,但我想使用SL_RATEPROP_NOPITCHCORAUDIO,这样在更改音频速率时就不会进行音调校正。而SL_RATEPROP_NOPITCHCORAUDIO是默认设置,因此无需更改

从OpenSL_ES_规范_1.0.1.pdf:

SL_RATEPROP_NOPITCHCORAUDIO以当前速率播放音频,但不进行音调校正

SL_RATEPROP_PITCHCORAUDIO以当前速率播放音频,但进行音调校正

我正在编写代码来扩展Cocos2d-x音频引擎


Cocos2d-x版本为3.7rc0,NDK版本为NDK-r10d。

您是否找到了解决此问题的方法?不幸的是,没有。我为OpenSLES SLPlaybackRateItf SetRate的Android项目添加了错误报告。SetRate无法正常工作:。关于这一点的其他讨论可以在这里找到:我明白了。谢谢你的回复!你找到解决这个问题的方法了吗?不幸的是,没有。我为OpenSLES SLPlaybackRateItf SetRate的Android项目添加了一个错误报告,该报告无法正常工作:。关于这一点的其他讨论可以在这里找到:我明白了。谢谢你的回复!
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);
    }
}