2014-01-07 5 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 사이의 설정 값 (playbackMaxRate 2000 내 S3 전화입니다, playbackMinRate 500입니다) 시도 다음은 스냅 코드입니다. 그러나 아무런 효과가 없으며, android NDK doc이 SL_IID_PLAYBACKRATE를 지원한다고 말했습니다. 내 코드에 문제가 있습니까? 고마워요.

+0

시험용 휴대 전화는 어느 Android 버전입니까? –

+0

내 테스트 전화는 삼성 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에서 작동합니다. 희망이 도움이됩니다.

+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을 시도했으나 효과가 없으며 "기능 지원되지 않음"을 출력합니다. 모토 G는 안드로이드 4.3 버전이어야합니까? –