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를 지원한다고 말했습니다. 내 코드에 문제가 있습니까? 고마워요.
시험용 휴대 전화는 어느 Android 버전입니까? –
내 테스트 전화는 삼성 s3 android 4.1 –