Мне удалось создать контекст OpenSL и все такое, чтобы он воспроизводил звук.
Но у меня все еще есть проблема: я установил samplesPerSec
для своего проигрывателя на 44.100 Hz
, но на самом деле он работает на ~ 70.000 Hz
. Как это можно исправить?
Что ж, я покажу вам, что я сделал (полностью на исходный код):
В PolyOpenSLInterface.cpp я инициализирую OpenSL и запускаю поставить буфер в очередь на мой SLAndroidSimpleBufferQueueItf
. Я создаю Player следующим образом:
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?)?
Спасибо за каждое предложение и помощь заранее!
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_48;
у вас частота дискретизации 48 кГц, но вы сказали, что пытаетесь воспроизвести звук в 44,1 кГц. И еще одна вещь из этой строкиlDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
- я вижу, что это 16-битные аудиоданные PCM на выборку. Но обычноSL_PCMSAMPLEFORMAT_FIXED_8
встречается в большинстве случаев. - person Reaz Murshed   schedule 12.06.2016