2016-06-02 5 views
1

Мне удалось создать контекст OpenSL и все, чтобы он воспроизводил звук.
Но у меня все еще есть проблема: я установил samplesPerSec для моего игрока в 44.100 Hz, но он действительно работает на ~ 70.000 Hz. Как можно это исправить?OpenSL на Android играет с более высокой скоростью, чем следовало

Ну я покажу вам, что я сделал (полный в Source Code):

В PolyOpenSLInterface.cpp Я инициализации OpenSL и начать enqueuing буфера к моим SLAndroidSimpleBufferQueueItf. Я создаю игрок следующий образ:

SLDataLocator_AndroidSimpleBufferQueue lDataLocatorIn; 
lDataLocatorIn.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; 
lDataLocatorIn.numBuffers = 1; 

SLDataFormat_PCM lDataFormat; 
lDataFormat.formatType = SL_DATAFORMAT_PCM; 
lDataFormat.numChannels = POLY_NUM_CHANNELS; 
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_44_1; //sampling rate 44.100Hz 
lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 
lDataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; 
if(POLY_NUM_CHANNELS > 1){ 
    lDataFormat.channelMask = SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_LEFT; 
} else { 
    lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER; 
} 
lDataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN; 

SLDataSource lDataSource; 
lDataSource.pLocator = &lDataLocatorIn; 
lDataSource.pFormat = &lDataFormat; 

SLDataLocator_OutputMix lDataLocatorOut; 
lDataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX; 
lDataLocatorOut.outputMix = mOutputMixObj; 

SLDataSink lDataSink; 
lDataSink.pLocator = &lDataLocatorOut; 
lDataSink.pFormat = NULL; 

const SLuint32 lSoundPlayerIIDCount = 2; 
const SLInterfaceID lSoundPlayerIIDs[] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; 
const SLboolean lSoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 

lRes = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj, &lDataSource, &lDataSink, lSoundPlayerIIDCount, lSoundPlayerIIDs, lSoundPlayerReqs); 
lRes = (*mPlayerObj)->Realize(mPlayerObj, SL_BOOLEAN_FALSE); 

Мой зарегистрированный обратный вызов выглядит следующим образом (я беру уже используемый буфер и записать следующие образцы в него и епдиеий буфер снова):

void OpenSLAudioInterface::queueCallback(SLAndroidSimpleBufferQueueItf caller, void* pContext){ 
    OpenSLAudioInterface *audioInterface = (OpenSLAudioInterface*) pContext; 
    if(audioInterface->buffer && audioInterface->getMixer()) { 
     int16_t *out = (int16_t*)audioInterface->buffer; 
     audioInterface->getMixer()->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER); 
     (*(audioInterface->mPlayerQueue))->Enqueue(audioInterface->mPlayerQueue, out, sizeof(int16_t)*POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS); 
    } 
} 

Так может кто-нибудь объяснить, почему звук воспроизводится ~2 times faster, чем это должно быть, и почему образцы, которые мне нужно смешивать, чтобы заполнить буфер, превышают 44.100 Гц в ~2?
Нужно ли использовать круглый буфер (это тот, который я использую для использования OpenSL?)?

Спасибо за все предложения и помощь заранее!

+0

'lDataFormat.samplesPerSec = SL_SAMPLINGRATE_48;' ваша частота дискретизации составляет 48 кГц, но вы сказали, что пытаетесь воспроизвести звук в 44,1 кГц. И еще одна вещь из этой строки 'lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;' - Я вижу, что это 16 бит на выборку аудио данных PCM. Но обычно 'SL_PCMSAMPLEFORMAT_FIXED_8' встречается в большинстве случаев. –

+0

Ох .. Я отредактировал вопрос, как я скорректировал его до 44.1, чтобы выполнить проекты по умолчанию .. И не должен ли int16_t использовать 16 бит? (Хотя я проверю его на 8 бит) – fodinabor

+0

@ReazMurshed nope 8bit шутит звук ужасно вверх ..., который должен быть 16 бит. – fodinabor

ответ

0

Так что я решил эту проблему.
Я фактически инициализировал OpenSL дважды и поэтому также начал писать два параллельных буфера из одного источника - это приводит к тому, что половина кадров не будет правильно воспроизводиться.