2014-01-07 3 views
1

Я создал аудио-инструмент с использованием NDK, для получения низкой латентности, я выбираю OpenSL для воспроизведения музыкальных файлов. Но мне не удалось изменить скорость воспроизведения музыки. Вот код оснастки:Android OpenSL не поддерживает SL_IID_PLAYBACKRATE?

int OpenSLSoundPool::createOggAudioPlayer(const char *filename, int rate){ 
    SLresult result; 
    AAsset* asset = AAssetManager_open(mMgr, filename, AASSET_MODE_UNKNOWN); 
    if (NULL == asset) { 
     return JNI_FALSE; 
    } 

    // open asset as file descriptor 
    off_t start, length; 
    int fd = AAsset_openFileDescriptor(asset, &start, &length); 
    assert(0 <= fd); 
    AAsset_close(asset); 

    // configure audio source 
    SLDataLocator_AndroidFD loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length}; 
    SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 
    SLDataSource audioSrc = {&loc_fd, &format_mime}; 

    // configure audio sink 
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; 
    SLDataSink audioSnk = {&loc_outmix, NULL}; 

    // create audio player 
    const SLInterfaceID ids[4] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME, SL_IID_PLAYBACKRATE}; 
    const SLboolean req[4] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fdPlayerObject, &audioSrc, &audioSnk, 
      4, ids, req); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // realize the player 
    result = (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // get the play interface 
    result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY, &fdPlayerPlay); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // get the seek interface 
    result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK, &fdPlayerSeek); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // get the mute/solo interface 
    result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO, &fdPlayerMuteSolo); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // get the volume interface 
    result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME, &fdPlayerVolume); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    // get playback rate interface 
    result = (*fdPlayerObject)->GetInterface(fdPlayerObject, 
      SL_IID_PLAYBACKRATE, &fdPlayerRate); 
    assert(SL_RESULT_SUCCESS == result); 


    SLuint32 capa; 
    result = (*fdPlayerRate)->GetRateRange(fdPlayerRate, 0, 
       &playbackMinRate, &playbackMaxRate, &playbackRateStepSize, &capa); 
    assert(SL_RESULT_SUCCESS == result); 

    result = (*fdPlayerRate)->SetRate(fdPlayerRate, playbackMaxRate); 
    assert(SL_RESULT_SUCCESS == result); 

    SLpermille SLrate; 
    result = (*fdPlayerRate)->GetRate(fdPlayerRate, &SLrate); 
    assert(SL_RESULT_SUCCESS == result); 

    // enable whole file looping 
    result = (*fdPlayerSeek)->SetLoop(fdPlayerSeek, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); 
    assert(SL_RESULT_SUCCESS == result); 
    (void)result; 

    return JNI_TRUE; 
} 

ключевым моментом является:

result = (*fdPlayerRate)->SetRate(fdPlayerRate, playbackMaxRate); 
assert(SL_RESULT_SUCCESS == result); 

Я попытался установить значение между playbackMaxRate и playbackMinRate (На мой S3 телефон, playbackMaxRate в 2000, playbackMinRate 500). Но никакого эффекта, док-станция NDK android заявила, что поддерживает SL_IID_PLAYBACKRATE. Есть ли что-то не так с моим кодом? Большое спасибо.

+0

Какая версия для Android - ваш тестовый телефон? –

+0

мой тестовый телефон samsung s3 android 4.1 –

ответ

2

Вы можете попытаться установить ограничения на текущие ограничения скорости на SL_RATEPROP_PITCHCORAUDIO. По умолчанию звуковые свойства SL_RATEPROP_NOPITCHCORAUDIO. Пример:

SLuint32 capa; 
result = (*fdPlayerRate)->GetRateRange(fdPlayerRate, 0, 
      &playbackMinRate, &playbackMaxRate, &playbackRateStepSize, &capa); 
assert(SL_RESULT_SUCCESS == result); 

result = (*fdPlayerRate)->SetPropertyConstraints(fdPlayerRate, 
        SL_RATEPROP_PITCHCORAUDIO); 

if (SL_RESULT_PARAMETER_INVALID == result) { 
    LOGD("Parameter Invalid"); 
} 
if (SL_RESULT_FEATURE_UNSUPPORTED == result) { 
    LOGD("Feature Unsupported"); 
} 
if (SL_RESULT_SUCCESS == result) { 
    assert(SL_RESULT_SUCCESS == result); 
    LOGD("Success"); 
} 

result = (*fdPlayerRate)->SetRate(fdPlayerRate, playbackMaxRate); 
assert(SL_RESULT_SUCCESS == result); 

Это может отличаться в зависимости от версии платформы и ее реализации. Это работает в моем Moto G. Hope, это помогает.

+0

Большое спасибо. Я добавляю код SetPropertyConstraints, но не влияю. Я играл в mp3-файл и midi-файл, какой файл вы играете на Moto G? –

+0

Форматы файлов MP3 и WAV –

+0

Я пробовал samsung s3 4.1.2, asus-nexus_7 4.2.1 и samsung note 2 4.3, оба они не имеют эффекта и распечатывают «Feature Unsupported». Moto G должен быть версией Android версии 4.3? –

Смежные вопросы